microsoft / microsoft/TypeScript

Discriminated union with 11+ items does not handle nullability same as union with <10 items

Open
#62,511 3 comments 0 reactions 0 assignees View on GitHub
Bug Domain: check: Big Unions Help Wanted
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

### 🔎 Search Terms

10 11 union undefined type
Nullability narrowing is inconsistent between type discriminated unions of <=10 items and >10 items

### 🕗 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

https://www.typescriptlang.org/play/?ts=5.9.2#code/PTAEFUDsEsHtNAd2gFwBagIyYNSlQKYC2AzqACawFmSwqhoCGk5ANgaJAK6uuMBG0VqgCeoEoyIdGZLjHhJUGADyYADPhTESAKHIEAxnwBOHdvUYBmAFygA3qBQiADgVsAiTO9ABfUAB97Rxc3UHcAJm8-QLl9ADNoSAJyAG4daDiACisAQgA6J1dQAF5SsK8ASjsdUFrQEFAAcitG-DJnWBISaH5WMUbYggSk8ka8zMwADjUAFkmKmrqDeBJYdjzWWABzbMsCkIq0nx09QxMzAgt1WwdC0M8ogKC7j0jfJ9uQj0tHwM-XDwzX7PL5hACswP+9wAbJDggCwgB2OEvMKTFGg9wATgxCM8amBg2GyTSGWy6nydxKZQeVUWtQaADlYKACMZjLBjKBMvxLloubymAA3ODGAD8CzqoGWkFW602O0Y6n2rkOOh8QA

### 💻 Code

```ts
// Union with 11+ items does not handle nullability same as union with <10 items
declare let a3: { type: "1" } | { type: "2" } | undefined;
if(a3!.type === "1"){
// 'a3' is possibly 'undefined'.(18048)
console.log(a3.type);
}

declare let a10: { type: "1" } | { type: "2" } | { type: "3" } | { type: "4" } | { type: "5" } | { type: "6" } | { type: "7" } | { type: "8" } | { type: "9" } | { type: "10" } | undefined;
if(a10!.type === "1"){
// No error (better behavior?)
console.log(a10.type);
}
```

### 🙁 Actual behavior

Complains about undefined for unions with >10 members, but not for unions <11

### 🙂 Expected behavior

It seems like it should not error in either case - the code inside the `if` can only execute if the `a3` variable is not undefined

### Additional information about the issue

Relevant function in checker.ts: getKeyPropertyName(). That is where the 10 magic value comes from.

Contributor guide

Open the contributing guide

Research direction

Start with the provided Playground reproduction and inspect checker.ts, especially getKeyPropertyName(), where the 10-item threshold is identified. Compare nullability narrowing for the two union sizes and consider the expected behavior stated in the issue: neither example should report undefined inside the guarded block.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.