Search code examples
typescripttypes

TypeScript keyof returning specific type


If I have the following type

interface Foo {
    bar: string;
    baz: number;
    qux: string;
}

can I use typeof to type a parameter such that it only takes keys of Foo that return string ('bar' or 'qux')?


Solution

  • Typescript 4.1 and above

    With the addition of the as clause in mapped types we can now simplify the original type to:

    type KeyOfType<T, V> = keyof {
        [P in keyof T as T[P] extends V? P: never]: any
    }
    

    Playground Link

    Original answer

    You can use conditional types in Typescript 2.8 :

    type KeysOfType<T, TProp> = { [P in keyof T]: T[P] extends TProp? P : never }[keyof T];
    
    let onlyStrings: KeysOfType<Foo, string>;
    onlyStrings = 'baz' // error
    onlyStrings = 'bar' // ok
    
    let onlyNumbers: KeysOfType<Foo, number>;
    onlyNumbers = 'baz' // ok
    onlyNumbers = 'bar' // error 
    

    Playground Link