Search code examples
typescriptgenericsmapped-types

Capturing generic parameters in mapped types


In typescript I'd like to use generic parameters that aren't a part of the signature. For example, I would like some code like the following...

type NotArray<T> = T extends Array<I> ? I: T;
type Test1 = NotArray<Array<number>>; // Resolves to 'number'
type Test2 = NotArray<string>> // Resolves to 'string'

This fails to compile with Cannot find name 'I'. If I change I to any, it will compile, but then the resolved type is any. Eg:

type NotArray<T> = T extends Array<any> ? any: T;
type Fail = NotArray<Array<number>>; // Resolves to 'any'

Is there a way to 'capture' the generic parameter to the array?


Solution

  • Just add infer keyword before I definition:

    type NotArray<T> = T extends Array<infer I> ? I: T;
    type Test1 = NotArray<Array<number>>; // Resolves to 'number'
    type Test2 = NotArray<string> // Resolves to 'string'
    

    See Type inference in conditional types