type Params = { readonly [N: string]: string }
type Props = Omit<{ readonly [N: string]: unknown }, 'params'>
type Load<Pa extends Params, Pr extends Props> = (context: { params: Pa }) => Pr
type ParamsOfLoad<L> = L extends Load<infer Pa, Props> ? Pa : never
type PropsOfLoad<L> = L extends Load<Params, infer Pr> ? Pr : never
type ResultOfLoadParams = ParamsOfLoad<(c: { params: { id: string } }) => { msg: 'hello' }>
type ResultOfLoadProps = PropsOfLoad<(c: { params: { id: string } }) => { msg: 'hello' }>
// ^ This is `never` even though `{ id: string }` extends Params
#extends does not work when I want to check an argument of a function
25 messages · Page 1 of 1 (latest)
Preview:```ts
type Params = {readonly [N: string]: string}
type Props = Omit<
{readonly [N: string]: unknown},
"params"
type Load<
Pa extends Params,
Pr extends Props
= (context: {params: Pa}) => Pr
type ParamsOfLoad<L> = L extends Load<infer Pa, Props>
? Pa
: never
...```
You can choose specific lines to embed by selecting them before copying the link.
When check whether A extends B and B is a fuction
The args of B have to extend the args of A, Instead of args A extending args B
Normally we are assigning values so, we can pass 'a' as a string. But when we pass a function we need to pass a function that will accept a string itself. The receiving type can be a wider type. The function becomes a receiver so needs args types as wide as the specified type.
Preview:ts type R = ((a: string | number) => null) extends ( a: string ) => null ? true : false // ^?
You can choose specific lines to embed by selecting them before copying the link.
So what you are saying is that I can't do what I'm doing?
why it works when it's the return type?
You can do what you want, but you need to use a small constraint
Try never as the Params in the extends check.
The return value has normal variance. If the function is called it will return and assign that value, pretty much the same as passing a value immediately
Preview:ts type R = ((a: {a: string}) => null) extends ( a: never ) => null ? true : false // ^?
You can choose specific lines to embed by selecting them before copying the link.
never is assignable to everything, the opposite of unknown really.
Okay this seems weird to me, it's highly probable that I don't know what never really means then
I thank you so much for your time and patience please bear with me
Can you explain it to me with sets?
If I understand right extends means just this is a subset of this right?
so in the case of the functions you wrote:
Here you are saying that the function (a: string | number) => null is part of the set of functions that are described as (a: string) => null
right?
How this should be translated then?
Never is an empty set, aka the bottom type, so it's within every other set or assignable to every type
!:var*
`!t6:variance`:
Here's the example with Dog and Animal, explaining co/contra/in variance:
- Covariance:
() => Dogis assignable to() => Animal, becauseDogis assignable toAnimal; it "preserves the direction of the assignability" - Contravariance:
(Animal) => voidis assignable to(Dog) => void, because something that expects anAnimalcan also take aDog; it "reverses the direction of the assignability" - Invariance:
(Animal) => Animalis not assignable to(Dog) => Dog, because not all returnedAnimals areDogs, and(Dog) => Dogis not assignable to(Animal) => Animal, because something expecting aDogcannot take any other kind ofAnimal
Thank you very much