Skip to content

"in keyof" type mapping incorrectly interacts with indexers #42436

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

Closed
LoganGerber opened this issue Jan 21, 2021 · 3 comments
Closed

"in keyof" type mapping incorrectly interacts with indexers #42436

LoganGerber opened this issue Jan 21, 2021 · 3 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@LoganGerber
Copy link

LoganGerber commented Jan 21, 2021

Bug Report

πŸ”Ž Search Terms

Indexer
Type mapping
Type resolution
Typing

πŸ•— Version & Regression Information

All versions available on the Typescript workbench.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// Matches to the names of all non-optional properties in T
type RequiredMembers<T extends object> = {
    [K in keyof T]?: undefined extends T[K] ? never : K;
}[keyof T];


type WorkingExampleType = {
    requiredString: string;
    requiredNumber: number;
    optionalBoolean?: boolean;
};

let x: RequiredMembers<WorkingExampleType>[] = ["requiredNumber", "requiredString"]; // Working example, only matches to the names of the required properties


type BrokenExampleType = {
    requiredString: string;
    requiredNumber: number;
    optionalBoolean?: boolean;
    [keyword: string]: any; // <-- Only difference between this type and WorkingExampleType
}

let y: RequiredMembers<BrokenExampleType>[] = ["requiredNumber", "requiredString"]; // <-- Errors on these strings. "Type 'string' is not assignable to type 'undefined'. (2322)"

πŸ™ Actual behavior

RequiredMembers<BrokenExampleType> resolves to undefined.

πŸ™‚ Expected behavior

RequiredMembers<BrokenExampleType> resolves to "requiredString" | "requiredNumber"

@MartinJohns
Copy link
Contributor

MartinJohns commented Jan 21, 2021

By design. Due to the indexer every string is a valid key, so keyof returning string is correct.

See #41966 for a workaround (omit the index signature).

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jan 21, 2021
@LoganGerber
Copy link
Author

Due to the indexer every string is a valid key, so keyof returning string is correct.

I don't think that's where my problem was. It's in [K in keyof T]?: undefined extends T[K] ? never : K;, specifically the undefined extends T[K] ? never : K; always resolving to never. I know that keyof should always return string, but the issue is with the values, not the keys.

@LoganGerber
Copy link
Author

Oh nevermind, I understand what you're saying now. It's the [keyof T] that's causing the issue when using it on BrokenExampleType, but it's working as intended. My bad, thanks for the help yall!

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

3 participants