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

No TS2367 error when using unary not #55702

Closed
kkmuffme opened this issue Sep 10, 2023 · 4 comments
Closed

No TS2367 error when using unary not #55702

kkmuffme opened this issue Sep 10, 2023 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@kkmuffme
Copy link

πŸ”Ž Search Terms

TS2367 unary not

πŸ•— Version & Regression Information

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

⏯ Playground Link

https://www.typescriptlang.org/play?#code/FAMwrgdgxgLglgewgAhgRgDxSQZxsgFQD4AKZAQwCcBzALkIEp6DkBTADxlYgBMdkIYALYAjVpWQB+ZAG9y9PJTgRqAX2T0Q5ADY5Ws4AEhKrGGEooA5JYDcwVcGDYIeZO2QBeVGjJoArMgMdnAgyGQAhO4MssgA9LHIAO4AFgCeAghslJQIEsnirJJGzq7pXux2DsAhYW6eHl5auvrRMsW4+GVulcBAA

πŸ’» Code

function t1<const T>( arg: T): T extends number ? {a: string} : false {
	return '';
}

const x = t1( 15 );
if ( !x ) { // why no error here?
	const y = x;
}

if ( x === false ) {
	const y = x;
}

πŸ™ Actual behavior

Only error for line 11, even though line 7 should give an error too, since it's logically the same behavior.

πŸ™‚ Expected behavior

Error for line 11 and line 7 since it's logically the same behavior.

Additional information about the issue

Vaguely the opposite of #44366

This issue is annoying, because of #44366 - since in some cases it only works with false and in some with unary not.

@jcalz
Copy link
Contributor

jcalz commented Sep 10, 2023

!x and x === false are not the same comparison, since !x only checks whether x is falsy as opposed to false.

The only way those are "logically the same behavior" is because we know that since x is of type {x: string} (but confusingly "" at runtime, why?) then !x and x === false are both false. So if (!x) {} and if (x === false) {} are the same as each other but also the same as if (3 > 5) {} or if (false) {}... but I wouldn't expect that to mean that the type checker should treat x === false and !x the same as each other or as 3 > 5 or as false. What am I missing here?

@kkmuffme
Copy link
Author

They are not identical in a general case but their result is identical in this case, as typescript knows the types.

And this is the basis of TS2367 too - it only works/reports an error because it is aware of the types. This logic should also extend to ! and === false.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Sep 13, 2023
@RyanCavanaugh
Copy link
Member

They are not identical in a general case but their result is identical in this case, as typescript knows the types.

This is just trading one inconsistency for another. We always allow

if (x) {

since x could be an actually-falsy value, e.g.

const arr: object[] = /* some array */;
const x = arr[3];
if (x) { // truthy according to type system

so it'd be inconsistent to allow

if (x) {
} else { // <- !x must be true
}

but not

if (x) {

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Working as Intended" 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 Sep 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants