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

Filtering keys does not work with generic types #40654

Closed
Pauan opened this issue Sep 20, 2020 · 3 comments
Closed

Filtering keys does not work with generic types #40654

Pauan opened this issue Sep 20, 2020 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@Pauan
Copy link

Pauan commented Sep 20, 2020

TypeScript Version: 4.1.0-dev.20200920

Search Terms: filter key generic

Code

// Selects all the keys from T which have a value of V
type SelectKeys<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];

//================================================================
// Using a concrete type works
interface Foo {
    yes: string;
    no: number;
}

let foo: Foo = {
    yes: "hello",
    no: 5
};

// This function can only be called with keys which have a value of string
function lookup<Key extends SelectKeys<Foo, string>>(key: Key): string {
    return foo[key];
}

lookup("yes");
lookup("no"); // This error is correct

//================================================================
// Using a generic type T does not work
class Bar<T> {
    private bar: T;

    constructor(bar: T) {
        this.bar = bar;
    }

    // This method can only be called with keys which have a value of string
    lookup<Key extends SelectKeys<T, string>>(key: Key): string {
        // This error is NOT correct
        return this.bar[key];
    }
}

new Bar<Foo>(foo).lookup("yes");
new Bar<Foo>(foo).lookup("no"); // This error is correct

Expected behavior:

No error occurs.

Actual behavior:

The following error occurs:

Type 'T[SelectKeys<T, string>]' is not assignable to type 'string'.
 Type 'T[T[keyof T] extends string ? keyof T : never]' is not assignable to type 'string'.
   Type 'T[keyof T]' is not assignable to type 'string'.
     Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'string'.
       Type 'T[string]' is not assignable to type 'string'.

Playground Link: [Link]

Related Issues: #28111 #30728 #38646

@jack-williams
Copy link
Collaborator

See #39972 and the associated links.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Sep 22, 2020
@RyanCavanaugh
Copy link
Member

👆

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants