Reputation: 163
I'm trying to create a type where the return value of a function depends on the value of another property, is this possible?
As far as I can tell, it's impossible to reference the interface you are defining as you are defining it.
Another approach to this would be saving the keyof T
in some kind of type (like K in keyof T
or similar) to be reused later in the class, but that doesn't seem to work
This is essentially what I want to do (although this
obviously does not work):
interface GenericType<T> {
column: keyof T;
genericFunction: () => T[this.column];
}
Let's say T has two keys:
a: number,
b: string
Then I want my generic type to be typed as
column: 'a',
genericFunction: () => number
and if column changes to 'b'
then genericFunction
should return string
.
Upvotes: 1
Views: 163
Reputation: 23692
You could do something like this:
interface GenericType<T, U extends keyof T> {
column: U;
genericFunction: () => T[U];
}
How to use it:
interface AB {
a: number
b: string
}
const a: GenericType<AB, "a"> = {
column: "a",
genericFunction() {
return 12; // the compiler ensures the return value is a number
}
};
Or, another way to use it with inference:
function makeGenType<T, U extends keyof T>(obj: T, propName: U): GenericType<T, U> {
return {
column: propName,
genericFunction() {
return obj[propName];
}
};
}
const genType = makeGenType({ a: 12, b: "ab" }, "b");
// Type of `genType` is: { column: "b", genericFunction: () => string }
Upvotes: 1