Suppose I have an interface in typescript as follows:
interface I1 {
name: string,
age: number
}
And I have another interface that accesses interface properties:
interface I2<T> {
getValue: (arg0: keyof T) => any
}
I want to be able to pass in another interface into I2 such that you can only pass in keys of T and it will return the type of that key.
So If I have
const record: I2<I1> = new Record()
I want
const name = record.getValue('name')
to return a string and
const age = record.getValue('age')
to return a number
The first part works – I can only pass in keys of I1
The second part doesn’t work.
I tried
interface I2<T> {
getValue: (arg0: keyof T) => T[keyof T]
}
but this makes that any call to getValue
will return a union number|string
.
I tried
interface I2<T> {
getValue: (arg0: keyof T) => T[arg0]
}
but this isn’t valid typescript
>Solution :
In order for getValue()
to represent a relationship between the particular key input and the type of the output, you’ll need to make it a generic method with its own type parameter K
constrained to keyof T
, like this:
interface I2<T> {
getValue: <K extends keyof T>(k: K) => T[K]
}
Now things should behave as expected:
interface I1 {
name: string,
age: number
}
declare const record: I2<I1>;
const name = record.getValue('name')
// const name: string
const age = record.getValue('age');
// const age: number