# Suggestion <!-- Please fill in each section completely. Thank you! --> ## 🔍 Search Terms - distributed conditional types - infer keyword ## ✅ Viability Checklist My suggestion meets these guidelines: * [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code * [x] This wouldn't change the runtime behavior of existing JavaScript code * [x] This could be implemented without emitting different JS based on the types of the expressions * [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.) * [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals). ## ⭐ Suggestion Doing this would allow the complete removal of an entire branch, and it's much more intuitive (the hanging `infer` stumped me a whole lot when I was learning). Before: ```typescipt InferringType<T> = T extends infer U ? U extends SomeConcreteType ? U : never : never ``` After: ```typescipt InferringType<T> = T extends SomeConcreteType infer U ? U : never ``` ### Alternatives 1. Something consistent with the [`as` keyword ](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html#key-remapping-in-mapped-types) in template string literal types e.g. ```typescipt InferringType<T> = T extends SomeConcreteType as U ? U : never ``` 2. No extra syntax, just smart control flow analysis on the type variable. ```typescipt InferringType<T> = T extends SomeConcreteType ? T // T extends SomeConcreteType on this branch : never // T does not extend SomeConcreteType on this branch ``` ## 📃 Motivating Example [This playground link](https://www.typescriptlang.org/play?#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) - has some documentation that should provide some context for the following code, but this is a pretty universal pattern anyway. Before: ```typescript type InferEventFromTypeMatch<TypeMatch extends string> = TypeMatch extends infer InferredTypeMatch ? InferredTypeMatch extends Event['type'] ? Extract<Event, AbstractEvent<InferredTypeMatch, any>> : InferredTypeMatch extends `${infer WildcardedTypeMatch}*` ? Event extends infer EventCase ? EventCase extends { type: `${WildcardedTypeMatch}${any}` } ? EventCase : never : never : never : never ``` After: ```typescript type InferEventFromTypeMatch0<TypeMatchString extends string> = TypeMatchString extends Event['type'] infer ExactTypeMatchString // Can give a much more meaningful label ? Extract<Event, AbstractEvent<ExactTypeMatchString, any>> : InferredTypeMatch extends `${infer WildcardedTypeMatch}*` ? Event extends { type: `${WildcardedTypeMatch}${any}` } infer WildcardTypeMatch // Can give a much more meaningful label here too ? WildcardTypeMatch : never : never // Only two hanging nevers, rather than four ``` ## 💻 Use Cases <!-- What do you want to use this for? What shortcomings exist with current approaches? What workarounds are you using in the meantime? -->