Closed as not planned
Description
π Search Terms
issue #14829
pull #56794 (The pull for 14829)
β Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
These are conditional type examples in the 2.8 release doc:
type Foo<T> = T extends { a: infer U; b: infer U } ? U : never;
type T10 = Foo<{ a: string; b: string }>; // string
type T11 = Foo<{ a: string; b: number }>; // string | number
type Bar<T> = T extends { a: (x: infer U) => void; b: (x: infer U) => void }
? U
: never;
type T20 = Bar<{ a: (x: string) => void; b: (x: string) => void }>; // string
type T21 = Bar<{ a: (x: string) => void; b: (x: number) => void }>; // string & number
The proposal is that the such generic types support NoInfer
, for example:
type Foo<T> = T extends { a: infer U; b: NoInfer<infer U> } ? U : never;
type T10 = Foo<{ a: string; b: string }>; // string
type T11 = Foo<{ a: string; b: number }>; // (expecting string)
type Bar<T> = T extends { a: (x: infer U) => void; b: (x: NoInfer< infer U>) => void }
? U
: never;
type T20 = Bar<{ a: (x: string) => void; b: (x: string) => void }>; // string
type T21 = Bar<{ a: (x: string) => void; b: (x: number) => void }>; // (expecting string)
π Motivating Example
Testing the latest dev version with pull #56794, these results were obtained:
type Foo<T> = T extends { a: infer U; b: NoInfer<infer U> } ? U : never;
>Foo : Foo<T>
>a : U
>b : NoInfer<U>
type T10 = Foo<{ a: string; b: string }>; // string
>T10 : string
>a : string
>b : string
type T11 = Foo<{ a: string; b: number }>; // never (expecting string)
>T11 : never <- WAS EXPECTING STRING
>a : string
>b : number
type Bar<T> = T extends { a: (x: infer U) => void; b: (x: NoInfer< infer U>) => void }
>Bar : Bar<T>
>a : (x: infer U) => void
>x : U
>b : (x: NoInfer<infer U>) => void
>x : NoInfer<U>
? U
: never;
type T20 = Bar<{ a: (x: string) => void; b: (x: string) => void }>; // string
>T20 : string
>a : (x: string) => void
>x : string
>b : (x: string) => void
>x : string
type T21 = Bar<{ a: (x: string) => void; b: (x: number) => void }>; // (expecting string)
>T21 : never <- WAS EXPECTING STRING
>a : (x: string) => void
>x : string
>b : (x: number) => void
>x : number
The location marked with <- WAS EXPECTING STRING show results of never
where string
was expected.
π» Use Cases
- What do you want to use this for?
- generic type inference