'Typescript , How to infer type from another property value?
For example, I have an interface with properties: key
and value
, I want to infer value type by the key.
interface Obj { a: number; b: string }
interface Param<K extends keyof Obj> {
key: K
value: Obj[K] // I want to infer this type
}
const p: Param<keyof Obj> = {
key: 'a',
value: '', // typescript can't infer this type, expect number
}
How can I do that ?
Solution 1:[1]
Obj[K]
means a value that can be gotten by indexing Obj
by any of the values in K
, not just the one key
is.
So, to use this structure, you need to specify which key is used more closely:
interface Obj { a: number; b: string }
interface Param<K extends keyof Obj> {
key: K
value: Obj[K]
}
const p: Param<'a'> = { // changed line
key: 'a',
value: '', // error
}
There's no way to infer the generic parameter, sadly.
If you already know what's in Obj
, there may be a better way to do this.
interface AParam {
key: 'a'
value: number
}
interface BParam {
key: 'b'
value: string
}
type Param = AParam | BParam;
const p: Param = {
key: 'a',
value: '', // error
}
This is the only approach that will work if you need the variable p
to be able to hold either key
, but still have the value
be the correct type.
Solution 2:[2]
You can reach this goal with the help of mapped types.
type ParamHelper<T> = { [K in keyof T]: { key: K; value: T[K] } };
type Param<T> = ParamHelper<T>[keyof ParamHelper<T>];
Solution 3:[3]
type param<o> = {
[k in keyof o]: {
key: k,
value: o[k]
}
}[keyof o];
const o = {a:1, b:2} as const
const a: param<typeof o> ={
key:'a',
value:1
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Half |
Solution 2 | stackoverflowuser234 |
Solution 3 | zyf0330 |