zerkms
zerkms

Reputation: 254944

Why always true conditional type in return does not type check in this case

I find

type B = { 
  foo: string;
  bar: number;
};

function get<F extends B, K extends keyof B>(f: F, k: K): F[K] {
  return f[k];
}

intuitively identical to

function get<F extends B, K extends keyof B>(f: F, k: K): F extends B ? F[K] : undefined {
  return f[k];
}

but the latter does not type check:

Type 'F[K]' is not assignable to type 'F extends B ? F[K] : undefined'.
  Type 'F["foo"] | F["bar"]' is not assignable to type 'F extends B ? F[K] : undefined'.
    Type 'F["foo"]' is not assignable to type 'F extends B ? F[K] : undefined'.
      Type 'string' is not assignable to type 'F extends B ? F[K] : undefined'.

Hence a question: what does TS compiler know about types that is not obvious to me?

Playground: http://www.typescriptlang.org/play/#code/C4TwDgpgBAQlC8UDeUBQUoDMD22BcUAzsAE4CWAdgOYDc6UARgIYkEUCuAtgxCXQL51M7CgGNgZbBShUIwADwAxKBAAewCBQAmhWABooAaRXrNOqAGsIIbJlgA+ABSYCigxYKGAlK5MbtunAA-FCKANqGALpQBCJaEJiUEFrI9CRy7CTSmGEWkQKoQA

Upvotes: 3

Views: 69

Answers (1)

jcalz
jcalz

Reputation: 328387

It's more like you know more than it does... the compiler doesn't try to do any deep analysis of conditional types that depend on unresolved generic type parameters. That is, the conditional type F extends B ? F[K] : undefined isn't really evaluated inside the function implementation, where F has yet to be specified with a concrete type. So while it's easy enough for you to see that F extends B ? F[K] : undefined must be the same as F[K], because the condition F extends B is the same as the generic constraint F extends B, the compiler doesn't even begin to do this (likely for performance reasons).

Upvotes: 3

Related Questions