Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type narrowing inconsistency with different union type definitions #60689

Closed
k8w opened this issue Dec 5, 2024 · 2 comments
Closed

Type narrowing inconsistency with different union type definitions #60689

k8w opened this issue Dec 5, 2024 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@k8w
Copy link

k8w commented Dec 5, 2024

🔎 Search Terms

type narrowing, union type, conditional type, discriminated union, type inference

🕗 Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about type narrowing and discriminated unions.

⏯ Playground Link

No response

💻 Code

// Worked!
function test1(value: { type: 'a' } | { type: 'b' }) {
    if (value.type === 'a' || value.type === 'b') { }
    else {
        // @ts-expect-error
        throw new Error(`asdf ${value.type}`)
    }
}

// Not Worked!
function test2(value: { type: 'a' | 'b' }) {
    if (value.type === 'a' || value.type === 'b') { }
    else {
        // @ts-expect-error
        throw new Error(`asdf ${value.type}`)
    }
}

### 🙁 Actual behavior

In test2, TypeScript fails to narrow the type of value within the if statement, even though the condition explicitly checks against all possible values of value.type. The else block, therefore, does not produce a type error, despite logically being unreachable. The @ts-expect-error directive is ignored. This is inconsistent with the behavior in test1, where the equivalent logic does correctly narrow the type. The only difference is the way the union type is defined: { type: 'a' } | { type: 'b' } versus { type: 'a' | 'b' }.

### 🙂 Expected behavior

TypeScript should consistently narrow the type in both test1 and test2. The else block in test2 should produce a type error, just as it does in test1, because the condition ensures that the else block is logically unreachable. The @ts-expect-error directive should correctly reflect this. The type narrowing behavior should not depend on the syntactic form of the union type definition.

### Additional information about the issue

This inconsistency leads to unpredictable behavior and reduces the reliability of TypeScript's type safety features. A consistent and predictable type narrowing mechanism is crucial for writing robust and maintainable code.
@MartinJohns
Copy link
Contributor

Duplicate of #31404.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Dec 5, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants