Uh oh!
There was an error while loading. Please reload this page.
Conditional types - #21316
Conversation
# Conflicts: # src/compiler/checker.ts
# Conflicts: # src/compiler/checker.ts # src/compiler/types.ts # tests/baselines/reference/api/tsserverlibrary.d.ts # tests/baselines/reference/api/typescript.d.ts
Leon Adler (leonadler)
commented
Mar 19, 2018
Sorry if there is a more appropriate place to post this, but thanks for the new (albeit sometimes complicated) ways to express behavior! typeIsValidArg<T>=Textendsobject ? keyofTextendsnever ? false : true : true;typeNumberOfArgs<TextendsFunction>=Textends(a: infer A,b: infer B,c: infer C,d: infer D,e: infer E,f: infer F,g: infer G,h: infer H,i: infer I,j: infer J)=>any ? (IsValidArg<J>extendstrue ? 10 :
IsValidArg<I>extendstrue ? 9 :
IsValidArg<H>extendstrue ? 8 :
IsValidArg<G>extendstrue ? 7 :
IsValidArg<F>extendstrue ? 6 :
IsValidArg<E>extendstrue ? 5 :
IsValidArg<D>extendstrue ? 4 :
IsValidArg<C>extendstrue ? 3 :
IsValidArg<B>extendstrue ? 2 :
IsValidArg<A>extendstrue ? 1 : 0) : 0;functionnumArgs<TextendsFunction>(fn: T): NumberOfArgs<T>{returnfn.lengthasany;}declarefunctionexampleFunction(a: number,b: string,c?: any[]): void;consttest=numArgs(exampleFunction);typePromisified<TextendsFunction>=Textends(...args: any[])=>Promise<any> ? T : (Textends(a: infer A,b: infer B,c: infer C,d: infer D,e: infer E,f: infer F,g: infer G,h: infer H,i: infer I,j: infer J)=> infer R ? (IsValidArg<J>extendstrue ? (a: A,b: B,c: C,d: D,e: E,f: F,g: G,h: H,i: I,j: J)=>Promise<R> :
IsValidArg<I>extendstrue ? (a: A,b: B,c: C,d: D,e: E,f: F,g: G,h: H,i: I)=>Promise<R> :
IsValidArg<H>extendstrue ? (a: A,b: B,c: C,d: D,e: E,f: F,g: G,h: H)=>Promise<R> :
IsValidArg<G>extendstrue ? (a: A,b: B,c: C,d: D,e: E,f: F,g: G)=>Promise<R> :
IsValidArg<F>extendstrue ? (a: A,b: B,c: C,d: D,e: E,f: F)=>Promise<R> :
IsValidArg<E>extendstrue ? (a: A,b: B,c: C,d: D,e: E)=>Promise<R> :
IsValidArg<D>extendstrue ? (a: A,b: B,c: C,d: D)=>Promise<R> :
IsValidArg<C>extendstrue ? (a: A,b: B,c: C)=>Promise<R> :
IsValidArg<B>extendstrue ? (a: A,b: B)=>Promise<R> :
IsValidArg<A>extendstrue ? (a: A)=>Promise<R> :
()=>Promise<R>) : never);declarefunctionpromisify<TextendsFunction>(fn: T): Promisified<T>;declarefunctionexampleFunction2(a: number,b: string,c?: any[]): RegExp;consttest2=promisify(exampleFunction2); |
sirian
commented
Mar 27, 2018
|
Ryan Cavanaugh (RyanCavanaugh)
commented
Mar 28, 2018
sirian please post code-fenced blocks instead of screenshots; no one wants to have to type in a dozen lines of code to add comments or observe behavior |
sirian are you asking a specific question? My example was not meant to be feature-complete, just a result of experimenting with 2.8 for a few minutes. It depends on typescripts |
Leon Adler (@leonadler) It was just a notice, that Ryan Cavanaugh (@RyanCavanaugh) Mi fault, I was sure I attached code. |
sirian
commented
Mar 29, 2018
Leon Adler (@leonadler) I have an idea! We could use reverse extends check. Look at scratch: |
Anders Hejlsberg (@ahejlsberg) I think many users will copy types from your examples from #21316 (comment).
|
Leon Adler (leonadler)
commented
Apr 13, 2018
sirian You seem to confuse "type A" with "object of type A". Similarily, when you write typeofObject==="function"TypeName<typeofObject>==="function"typeofObject.create(Object.prototype)==="object"TypeName<Object>==="object"classA{}typeofA==="function"TypeName<typeofA>==="function"typeof(newA())==="object"TypeName<A>==="object" |
How is it possible to do following? TextendsR[] ? BoxedArray<R> : BoxedValue<T> |
Po Chen (princemaple)
commented
May 10, 2018
Umed Khudoiberdiev (@pleerock) T extends (infer R)[] |
Umed Khudoiberdiev (pleerock)
commented
May 10, 2018
Po Chen (@princemaple) thanks it worked. Actually BoxedArray<T[number]> worked as well but such syntax wasn't obvious to me |



This PR introduces conditional types which add the ability to express non-uniform type mappings. A conditional type selects one of two possible types based on a condition expressed as a type relationship test:
The type above means when
Tis assignable toUthe type isX, otherwise the type isY. Evaluation of a conditional type is deferred when evaluation of the condition depends on type variables inTorU, but is resolved to eitherXorYwhen the condition depends on no type variables.An example:
Conditional types in which the checked type is a naked type parameter are called distributive conditional types. Distributive conditional types are automatically distributed over union types during instantiation. For example, an instantiation of
T extends U ? X : Ywith the type argumentA | B | CforTis resolved as(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y).In instantiations of a distributive conditional type
T extends U ? X : Y, references toTwithin the conditional type are resolved to individual constituents of the union type (i.e.Trefers to the individual constituents after the conditional type is distributed over the union type). Furthermore, references toTwithinXhave an additional type parameter constraintU(i.e.Tis considered assignable toUwithinX).Notice that
Thas the additional constraintany[]within the true branch ofBoxed<T>and it is therefore possible to refer to the element type of the array asT[number]. Also, notice how the conditional type is distributed over the union type in the last example.The distributive property of conditional types can conveniently be used to filter union types:
Conditional types are particularly useful when combined with mapped types:
Combining all of the above to create a
DeepReadonly<T>type that recursively makes all properties of an object read-only and removes all function properties (i.e. methods):Similar to union and intersection types, conditional types are not permitted to reference themselves recursively (however, indirect references through interface types or object literal types are allowed, as illustrated by the
DeepReadonly<T>example above). For example the following is an error:For further examples see the tests associated with the PR.
EDIT: See #21496 for type inference in conditional types.
Fixes#12215.
Fixes#12424.