Upgrading to Typescript 4.1 and beyond
By incorporating the as
clause in mapped types, we can streamline the original type definition to:
type KeyOfType<T, V> = keyof {
[P in keyof T as T[P] extends V ? P : never]: any
}
Playground Link
Initial Response
You have the option to utilize 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