So i was going through the documentation on typescript and am not able to get my head around this concept.
So the documentation states :-
In instantiations of a distributive conditional type T extends U ? X : Y, references to T within the conditional type are resolved to individual constituents of the union type (i.e. T refers to the individual constituents after the conditional type is distributed over the union type). Furthermore, references to T within X have an additional type parameter constraint U (i.e. T is considered assignable to U within X).
I cannot understand the part T refers to the individual constituents after the conditional type is distributed over the union type.
Can anyone please explain this to me. An example of the same would be highly appreciated, the one in the documentation is not very clear to me.
Hmm, I just read through the documentation and it makes sense to me... I don't know if I can explain it any better than that, but let's go through it. In what follows, and
...x..., means "some expression in whichxmight appear".In this case, a type parameter means a generic type parameter, and a naked type parameter is a type expression where the type parameter appears alone and is not part of some more complex type expression. And the checked type is the type appearing before
extends. Let's see some examples:type A<T> = string extends T ? "yes" : "no"This is not a distributive conditional type. The checked type isstring, which is not a generic type parameter.type B<T> = {x: T} extends {x: number} ? "yes" : "no"This is not a distributive conditional type. The checked type is{x: T}, which has the type parameterTin it, but is not a naked type parameter.type C<T> = T extends string ? "yes" : "no"This is a distributive conditional type; the checked type isT, which is a naked generic type parameter.This is the essence of what a distributive property does. If you have a type alias
F<T>defined to be a distributive conditional type, as in:Then
F<T>will distribute over unions, meaning that for any typesAandB, the typeF<A | B>will be equivalent to the typeF<A> | F<B>This is the part that confused you, but it's just explaining how the distribution works. It's saying that to evaluate
F<A | B>, you should evaluateF<A> | F<B>. So forF<A>, you takeF<T> = T extends ...T... ? ...T... : ...T...and plug inAforT(to getA extends ...A... ? ...A... : ...A...), and then plug inBforT(to getB extends ...B... ? ...B... : ...B...), and then unite them.Let's go through a concrete example:
What is this:
Well, here's how not to do it:
I just plugged
"a" | "b" | 0 | trueintoTwithout distributing, and that's wrong. Here's how to do it correctly:See, we took the "individual constituents of the union" and replaced
Twith each one of them in turn.Okay, I hope that makes more sense now. Good luck!