Let's say I have the generic function:
function f<T, K extends keyof T>(obj: T, key: K) {
...
}
I would like to enforce the type of T[K]
so I could perform type specific actions. For example, using string:
function f<T, K extends keyof T>(obj: T, key: K): string {
return obj[key].toLowerCase();
}
Is this at all possible without casting things to any
?
Edit: To clarify, I'm looking for the ability to disallow certain keys based on the resulting type. Using the example above, something like:
f({a: 123, b: 'abc'}, 'b') //No errors
f({a: 123, b: 'abc'}, 'a') //Typescript error, T['a'] is not string
To restrict property names to only those having string
value types you can use conditional types in conjunction with mapped types:
type StringProperties<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T];
declare function f<T>(obj: T, key: StringProperties<T>): string;
f({a: 123, b: 'abc'}, 'b') // No errors
f({a: 123, b: 'abc'}, 'a') // Error: Argument of type '"a"' is not assignable to parameter of type '"b"'.
Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With