typescripttypescript-genericstypescript-conditional-types

Why my constrained generic type in conjunction with a conditional type doesn't work as expected?


The following Typescript code snippet produces an error

function importedF<R extends string>(a: R extends string ? number : never) {}

function genericF<T extends string>() {
  importedF<T>(1);
}

where the error is on the parameter 1 passed to importedF and reads

Argument of type 'number' is not assignable to parameter of type 'T extends string ? number : never'.ts(2345)

Please help me understand why Typescript doesn't understand that T is indeed a string and thus the conditional statement should result in number. I'm looking for understanding rather than workaround.


Solution

  • This is considered a design limitation of TypeScript, as described at microsoft/TypeScript#51523 and issues linked within.

    If you have a conditional type that depends on a generic type parameter, TypeScript mostly just defers evaluation of it. Inside genericF(), T is generic, and TypeScript doesn't know exactly what it is yet, so the relevant type T extends string ? number : never is deferred. TypeScript doesn't even try to evaluate it. You might hope that because T has a constraint TypeScript could use it to partially (or wholly) evaluate the type instead of deferring it, but that doesn't happen. So TypeScript doesn't know what might be assignable to T extends string ? number : never, and it complains about 1.