Based on the answer at In TypeScript, how to get the keys of an object type whose values are of a given type? I put together this worked example answering your question specifically ( see playground ) but the hard part is really from the other answer.
type KeysMatching<T,V> = keyof { [ P in keyof T as T[P] extends V ? P : never ] : P };
function myFunction<T>(object: T, key: KeysMatching<T,string> ){
// ...
}
myFunction({keyA: "hello", keyB: 123}, "keyA") // OK
myFunction({keyA: "hello", keyB: 123}, "keyB") // error: `keyB` must be of type string but is number
I quite like the form of extracting a PickValues<T,V>
type which filters the properties of T to only those with values in V. Then simply use keyof
on that...
type PickValues<T,V> = { [ P in keyof T as T[P] extends V ? P : never ] : T[P] }
type Picked = PickValues<{keyA: "hello", keyB: 123},string>;
// type Picked = {
// keyA: "hello";
// }
//Your case
function myFunction<T>(object: T, key: keyof PickValues<T,string> ){
// ...
}
myFunction({keyA: "hello", keyB: 123}, "keyA") // OK
myFunction({keyA: "hello", keyB: 123}, "keyB") // error: `keyB` must be of type string but is number
Incidentally, this strategy can then be generalised to do the opposite and create an OmitValues<T,V>
type...
type OmitValues<T,V> = { [ P in keyof T as T[P] extends V ? never : P ] : T[P] }
type Omitted = OmitValues<{keyA: "hello", keyB: 123},string>;
// type Omitted = {
// keyB: 123;
// }
Finally, it can also be repurposed to extract only properties which are of an Optional nature...
type OptionalValues<T> = { [ P in keyof T as undefined extends T[P] ? P : never ] : T[P] }
type Optional = OptionalValues<{keyA?: "hello", keyB: 123}>;
// type Optional = {
// keyA?: "hello" | undefined;
// }