-
-
Notifications
You must be signed in to change notification settings - Fork 568
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
KeysOfUnion
: Fix assignability with keyof
#1009
base: main
Are you sure you want to change the base?
Conversation
? keyof ObjectType | ||
: never; | ||
export type KeysOfUnion<ObjectType> = | ||
// Hack to fix https://github.com/sindresorhus/type-fest/issues/1008 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way not hack?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be, but I couldn't figure out anything else.
Do you have any ideas or suggestions?
expectType<'a' | 'b'>(actual3); | ||
|
||
// KeysOfUnion<T> should NOT be assignable to keyof T | ||
type Assignability1<T, _K extends keyof T> = unknown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add test:
type Assignability1<T extends UnknownRecord, K extends keyof T> = unknown;
type Test1<T extends UnknownRecord> = Assignability1<T, KeysOfUnion<T>>; // should error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Emiyaaaaa The test you suggested doesn’t seem to produce an error:
type Assignability5<T extends UnknownRecord, _K extends keyof T> = unknown;
type Test5<T extends UnknownRecord> = Assignability5<T, KeysOfUnion<T>>; // Doesn't error
However, adding slightly different constraints does produce the expected error:
type Assignability5<T extends Record<string, unknown>, _K extends keyof T> = unknown;
// @ts-expect-error
type Test5<T extends Record<string, unknown>> = Assignability5<T, KeysOfUnion<T>>; // Does error
type Assignability5<T extends object, _K extends keyof T> = unknown;
// @ts-expect-error
type Test5<T extends object> = Assignability5<T, KeysOfUnion<T>>; // Does error
Unsure what's happening here, any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have idea right now, maybe it's a bug of Typescript I'm not sure. I'll try to look into this interesting issue later
Fixes #1008
To make
keyof T
assignable toKeysOfUnion<T>
, we can simply add an union withkeyof ObjectType
to the existing type, as shown below.However, I couldn’t find a straightforward way to prevent
KeysOfUnion<T>
from being assignable tokeyof T
.Instead, I reworked the implementation to use
UnionToIntersection
, which resolves both issues.There's another hack I figured out while experimenting, this also solves both the issues, but it's very hacky:
Playground