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

Empty types and types with never as a key behave differently #56691

Open
kazatsuyu opened this issue Dec 6, 2023 · 6 comments Β· May be fixed by #56974
Open

Empty types and types with never as a key behave differently #56691

kazatsuyu opened this issue Dec 6, 2023 · 6 comments Β· May be fixed by #56974
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@kazatsuyu
Copy link

kazatsuyu commented Dec 6, 2023

πŸ”Ž Search Terms

Mapped type
unknown

πŸ•— Version & Regression Information

  • This changed between versions 4.7.4 and 4.8.4

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.4.0-dev.20231206#code/CYUwxgNghgTiAEYD2A7AzgF3gVwFw5QGsUkB3FAbgCgqMBPABwQEF4BeeAbwG0BpeAJYp4KEADcQMALr4oKOgF8qAemXx1APQD8NVfABySeAFEYMJDCrJ0WKPhTYIEeAB8CoAGZCQwV1wXsONR66vDaumqm5pbWmPAARvaOzm7YKJ7evm6sHNjBaqHhQA

πŸ’» Code

declare const u: unknown;

type A = {[K in never]: any}
//   ^?

// No Error
const a: null | undefined | {} = u;
//    ^?

// Error
const b: null | undefined | A = u;
//    ^?

πŸ™ Actual behavior

The types a and b appear to be the same, but only the assignment to b causes an error.

πŸ™‚ Expected behavior

I'm not sure which is better, I think it's either no error or both errors.

Additional information about the issue

Both were errors in version 4.7.4

@MartinJohns
Copy link
Contributor

MartinJohns commented Dec 6, 2023

What is that mapped type supposed to do?

Regardless, this seems intentional: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-8.html#improved-intersection-reduction-union-compatibility-and-narrowing

TypeScript now recognizes this, and allows assignments from unknown to {} | null | undefined.

@kazatsuyu
Copy link
Author

kazatsuyu commented Dec 6, 2023

If the possible assignment of unknown to null | undefeind | {} is intentional, then the behavior of a is correct, but b should not be an error.

@jcalz
Copy link
Contributor

jcalz commented Dec 6, 2023

I suggest simplifying the example to something like type A = {[K in never]: any} which reproduces the behavior without the added distraction of conditional types.

Relevant: #49119 and #49119 (comment)

@kazatsuyu
Copy link
Author

Well, it certainly looks like the problem is not that I mapped {}, but that I created a type with never key.

@kazatsuyu kazatsuyu changed the title Empty mapped type and unknown behave strangely Empty types and types with never as a key behave differently Dec 6, 2023
@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Dec 8, 2023

I suppose the steelmanned version of the issue looks like this

export  {}
declare const u: unknown;
type Point = { x: number, y: number };

declare function foo<T, K extends keyof T>(obj: T, keys: K[], rest: Omit<T, K> | null | undefined): void;
const p: Point = { x: 0, y: 0 };
// Error, but should OK
foo(p, ["x", "y"], u);

@RyanCavanaugh
Copy link
Member

I'm not committing to take a fix for this since it's pretty niche, but if it's straightforward and doesn't break/slow down something else, we can take a PR

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Dec 8, 2023
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants