I'm interested in having a function that can operate generically on any keyof T
, but with an assertion that T[K]
is of a specific type (ie string
). I think this is best illustrated by this code sample:
interface FooBar {
x: string;
y: number;
}
function foo<K extends keyof FooBar, ???>(propertyName: K, fooBar: FooBar) {
const value = fooBar[propertyName];
// I want the type of value to be `string`
}
What can I put in for ??? to have fooBar[propertyName]
be typed as a string
instead of a string | number
string | number
? And I'd also like propertyName
to only have a valid value of 'x'
(obviously in practical circumstances there would be more than one string field, in which case it would be 'stringField1' | 'stringField2'
etc.
Is this possible with TypeScript?
Thank you!
You can create a type that extracts only the keys from your source object that correspond to string values in that object
interface FooBar {
x: string;
y: number;
}
type StringKeys<T> = {
[P in keyof T]: T[P] extends string? P: never;
}[keyof T]
function foo<K extends StringKeys<FooBar>>(propertyName: K, fooBar: FooBar):string {
const value = fooBar[propertyName];
return value
}
You don't have to explicitly have a type parameter for the property type typescript can infer it.
The StringKeys type works by creating a mapped type of [key]:[key]
('x':'x') for string valued properties and [key]:never
('y':never) for non string properties. The [keyof T] at the end will return all potential valeus for that objects properties. Never is special therefore excluded from this list.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.