why won't union narrow when conditional value is a generic param?

1 day ago 3
ARTICLE AD BOX

Sandbox

When working with a union type that's discriminated based on whether a property (val) is set or not, the type doesn't seem to narrow correctly if the property is a generic param (T). If I change it to be a type that would satisfy the same generic param (eg, SomeObj, {foo:3}, {foo:3, baz:5}, etc), then the type is narrowed correctly:

type SomeObj = { foo: 3 }; const func = <T extends SomeObj>(x: { sub: { val: T }; val?: undefined; } | { val: T; // changing this to SomeObj/etc fixes it }) => { const z = x.val ?? x.sub.val; // error: Property 'sub' does not exist on type '{ val: T; }' if (x.val === undefined) { type X = typeof x; // not narrowed const w = x.sub.val; // same error } }

The only way I can reason this in my mind is that it thinks that some possible value of T is undefined, but that shouldn't be possible since it's required to extend SomeObj, right? Plus, even if I change val: T to val: Exclude<T, undefined> it doesn't help.

Am I misunderstanding something about generics work here, or is this just a limitation of the type checker?

Read Entire Article