-
Notifications
You must be signed in to change notification settings - Fork 13k
Description
π Search Terms
10 11 union undefined type getKeyPropertyName discriminated
π Version & Regression Information
- This changed between versions 4.2.3 and 4.3.5 (before it would complain about undefined in both cases)
β― Playground Link
π» Code
interface A {
subType: "b";
type: "a";
}
declare let orderDependent:
| { type: "1" }
| A
| { type: "2" }
| { type: "3" }
| { type: "4" }
| { type: "5" }
| { type: "6" }
| { type: "7" }
| { type: "8" }
| { type: "9" }
| { type: "10" }
| undefined;
if(orderDependent!.type === "a"){
// 'orderDependent' is possibly 'undefined'.(18048)
console.log(orderDependent.type);
}
declare let orderDependent2:
| { type: "1" }
| A2
| { type: "2" }
| { type: "3" }
| { type: "4" }
| { type: "5" }
| { type: "6" }
| { type: "7" }
| { type: "8" }
| { type: "9" }
| { type: "10" }
| undefined;
interface A2 {
subType: "b";
type: "a";
}
if(orderDependent2!.type === "a"){
// No error (correct behavior?)
console.log(orderDependent2.type);
}
π Actual behavior
TypeScript may emit a possibly 'undefined'
error depending on the order in which types are defined.
Whether that error should be there in the first place is another question (#62511)
π Expected behavior
Type order should not impact type checking
Additional information about the issue
Cause investigation
Relevant function in checker.ts: getKeyPropertyName()
That function tries to find the "discriminated union key" and index the type union by it.
The logic is quite simple: find the first property of literal type among any union members (starting from the first) and try to index by it. If that property successfully discriminated the union, use it as an index. Otherwise fallback to slower check.
The union members are sorted by typeId, which is assigned sequentially in order in which the types are created.
In the linked example, the true discriminator is type
. However if first union member has another literal type property appear earlier (subType
), it is falsely selected as index, and indexing fails.
Related issue: #62511