繁体   English   中英

如何根据另一个属性的值定义一个属性的类型

[英]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
};

在上面的示例中,如果Ttypeof targetMap ,则Filter["value"]可能类型是stringbooleanstring 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM