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 fails to account for multiple conditions #53072

Open
ljharb opened this issue Mar 3, 2023 · 3 comments
Open

Type narrowing fails to account for multiple conditions #53072

ljharb opened this issue Mar 3, 2023 · 3 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@ljharb
Copy link
Contributor

ljharb commented Mar 3, 2023

Bug Report

πŸ”Ž Search Terms

type narrowing

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________

⏯ Playground Link

https://tsplay.dev/mAJ91W

πŸ’» Code

function isNaN(x: unknown): x is number {
	return x !== x;
}
function SameValue(x: unknown, y: unknown): x is typeof y {
	if (x === y) { // 0 === -0, but they are not identical.
		if (x === 0) { return 1 / x === 1 / y; }
		return true;
	}
	return isNaN(x) && isNaN(y);
};

πŸ™ Actual behavior

The y in 1 / y has a type error.

πŸ™‚ Expected behavior

Since this is inside a block where x === y, and also where x === 0, TS should be able to statically know that x and y are of type number (since both of them is definitively a zero, either +0 or -0). I shouldn't need the y === 0 check just to please TS.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Mar 3, 2023
@fatcerberus
Copy link

fatcerberus commented Mar 3, 2023

function isNaN(x: unknown): x is number

For the record, this is wrong as it implies that x is NOT number if the function returns false (UDTGs are treated as exhaustive). See #15048.

function SameValue(x: unknown, y: unknown): x is typeof y

This simply expands to x is unknown. You'd need to make it generic to do what this signature implies, but even then you'd probably run into #15048 again.

@ljharb
Copy link
Contributor Author

ljharb commented Mar 3, 2023

@fatcerberus thanks, that's fair about the isNaN thing - unfortunately TS doesn't allow is NaN.

the x is typeof y isn't the important part; replace it with boolean and the same type error appears for this issue, but thanks for the pointer :-)

@fatcerberus
Copy link

Yeah, I figured the return signature of SameValue was irrelevant to the main issue, but didn't want to develop any misconceptions about how type predicates work, lest another duplicate of #15048 shows up πŸ˜‰

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants