Reputation: 6662
An example demonstrates my question better than words:
interface X {
a: number,
b: string
}
interface KeyValue<T> {
key: keyof T,
value: T[this['key']]
}
const keyValue: KeyValue<X> = {
key: 'a',
value: 'Error! this should be a number'
};
I want the type of value
to be based on value of key
. I mean if key
is a, then I need the type of value
to be the same as type of X[a]
, which is number
. But currently, the type of value
is string | number
which is the union type of all value types in X
.
Can I achieve this with current typescript features?
Upvotes: 2
Views: 603
Reputation: 249606
You can't do it directly you need an extra type parameter
interface X {
a: number,
b: string
}
interface KeyValue<T, K extends keyof T> {
key: K,
value: T[this['key']] // or T[K]
}
const keyValue: KeyValue<X, 'a'> = {
key: 'a',
value: 0
};
To avoid typing the name of the property twice you can use a function to help with the creation. You need a fi function that returns a function as Typescript does not allow partial type argument inference yet
function newY<T>() {
return function <K extends keyof T>(p: Y<T, K>) {
return p;
}
}
let xx = newY<X>()({ key: 'a', value:0})
Upvotes: 1