Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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')?

like image 481
Levi Botelho Avatar asked Apr 10 '18 11:04

Levi Botelho


People also ask

What does Keyof return?

keyof T returns a union of string literal types. The extends keyword is used to apply constraints to K, so that K is one of the string literal types only. extends means “is assignable” instead of “inherits”' K extends keyof T means that any value of type K can be assigned to the string literal union types.

What does Keyof typeof do?

keyof is a keyword in TypeScript which is used to extract the key type from an object type.

What is ?: In TypeScript?

What does ?: mean in TypeScript? Using a question mark followed by a colon ( ?: ) means a property is optional. That said, a property can either have a value based on the type defined or its value can be undefined .


1 Answers

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 Tyepscript 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

like image 122
Titian Cernicova-Dragomir Avatar answered Oct 03 '22 01:10

Titian Cernicova-Dragomir