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

keyof should always include remapped keys #45923

Conversation

weswigham
Copy link
Member

Fixes #45825

To do this, I've extracted some of the functionality of resolvemappedTypeMembers into a common helper and reused it in getIndexTypeForMappedType. Doing this correctly necessitates looking at the apparent keys of the input MappedType's modifiersType if present, which causes new circularity issues in some edge cases involving infer conditionals - to avoid those, we defer expanding the keyof in cases where the constraint remains generic, and instead handle membership testing later in relationship checking, with a new relationship rule that can pull the concrete key names out of a target generic keyof MappedType<T> type. If you have something that is generic (because, eg, it has a homomorphic mapping over the properties of a type with both generic and nongeneric parts), you can still assign to the known bits of the (remapped) key list. In this way a still-generic keyof {[X in keyof (Whatever & T) as Modify<X>]: Stuff} can behave like a foreach K in (keyof Whatever | Keyof T) -> Modify<K> on the target side.

Eg,

function func<T>() {
    type Composite = T & { "a key": any; [idx: string]: any };
    type Modify<X> = [X]extends ["a key"] ? "b key" : never;
    const key: keyof {[X in keyof Composite as Modify<X>]: any} = "b key";
}

now works, while it did not before.

As a nice side effect of reusing more mapped type member machinery, this discussion is pretty neatly resolved - since the string indexer is mapped to never, the number type is no longer included.

…p rule for relating generic keyof MappedType to handle remapped keys
@typescript-bot typescript-bot added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Sep 17, 2021
@weswigham weswigham changed the title keyof should always includes remapped keys keyof should always include remapped keys Sep 17, 2021
@weswigham
Copy link
Member Author

Ping @ahejlsberg for a formal review when you get a chance~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Milestone Bug PRs that fix a bug with a specific milestone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

keyof loses known keys when remapping an object type with a symbol key to remove a string index signature
3 participants