![](/img/trans.png)
[英]Conditonal typescript type property based on another property's value
[英]How to define type of a property based on another property's value
const targetMap = {
name: "this is a string",
age: 23,
isAlive: false
};
type Filter<T> = {
fieldName: keyof T,
value: T[fieldName] // <-------------
};
const filter: Filter<typeof testMap> = {
fieldName: "name",
value: 123, // error
value: false, // error
value: "string", // ok
};
在上面的示例中,如果T
是typeof targetMap
,则Filter["value"]
可能类型是string
、 boolean
和string
; Filter["fieldName"]
每个可能值都是"name"
、 "age"
和"isAlive"
。
这是可行的,但我想要的是当我将"fieldName"
设置为"age"
,值的类型必须是number
或者"name"
必须是string
。
这在打字稿中可能吗? (或者是否有任何关于此的讨论可能会有所帮助?)
添加第二个通用参数K
与密钥使用的名称:
const targetMap = {
name: "this is a string",
age: 23,
isAlive: false
};
type Filter<T, K extends keyof T> = {
fieldName: K,
value: T[K]
};
const filter: Filter<typeof targetMap, 'name'> = {
fieldName: "name",
value: "...",
};
为了实现结果,我们需要定义字段键属性。 考虑:
const targetMap = {
name: "this is a string",
age: 23,
isAlive: false
};
type Filter<T, K extends keyof T> = {
fieldName: K,
value: T[K]
};
const filter: Filter<typeof targetMap, 'name'> = {
fieldName: "name", // only possible value is "name"
value: 'John', // only possible value is value of type string
};
如果我们想在不使用泛型类型的情况下推断键并通过值推断它,我们可以通过值构造函数来实现。 这是我们如何从我知道的值中获取类型的唯一方法。 考虑:
type Filter<T, K extends keyof T> = {
fieldName: K,
value: T[K]
};
const createFilter = <T, K extends keyof T>(obj: T, fieldName: K, value: T[K]): Filter<T,K> => ({
fieldName,
value,
})
// all arguments are type safe and checked
const filter = createFilter(targetMap, 'name', 'John');
使用值构造函数允许我们在参数之间创建依赖关系,因此类型K
是从fieldName
参数推断出来的,而value
参数被缩小到T[K]
。 看看我们的函数返回Filter<T,K>
如此完全正确的对象,它与所需的类型匹配。
在 Github( https://github.com/microsoft/TypeScript/issues/36444 )上打开一个问题后,我发现我们可以使用这样的东西:
type Filter<T> = { [K in keyof T]: {
fieldName: K;
operator: "like" | "equal" | "notLike" | "notEqual",
value: T[K]
} }[keyof T]
它有效!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.