Typescript 接口从同一接口的另一个属性设置属性类型

时间:2021-02-12 20:01:31

标签: typescript types interface

我有一个包含两个属性的接口,我希望第二个属性类型等于第一个属性,例如第一个属性类型是字符串。

interface Argument {
  type: any;
  allowedValues: [insert way to infer type from `type` property]
}

const a: Argument = {
  type: 'string',
  allowedValues: 'test', // only because `type` property is a string
}

type 属性可以是任何东西,但 allowedValues 的类型应该与 type(或它的数组)相同

1 个答案:

答案 0 :(得分:1)

TypeScript 中没有与您认为有效的 argument 完全对应的特定具体类型,其中 allowedValues 属性必须与 type 属性具有相同的类型。如果您希望能够在 TypeScript 中完全表示这一点,您可能需要将其更多地视为 generic constraint,并使用辅助函数而不是类型注释来验证任何给定的候选值符合约束:

    interface Argument<T> {
      type: T;
      allowedValues: T
    }
    const asArgument = <T,>(a: Argument<T>) => a;

这里我们创建了一个通用类型 Argument<T>,它跟踪相关的 typeallowedValues 属性的类型。你可以测试一下:

const a = asArgument({
  type: 'string',
  allowedValues: 'test', // okay
});

asArgument({
  type: 123,
  allowedValues: 456
}); // okay

asArgument({
  type: 'string',
  allowedValues: 456 // error! Type 'number' is not assignable to type 'string'
})

如果您尝试为 allowedValues 赋予与 type 不同类型的值,则会出现错误。


请注意,通过使您的 Argument 类型泛型,您需要在需要跟踪此约束的任何位置拖动额外的泛型类型参数 T。我想将 Argument 的所有提及更改为 Argument<T> 并将 T 添加到任何必要的范围。因此,我建议仅将此约束用于开发人员提交的参数的初始验证,然后将其扩展为具体类型,如 Argument<any>,以用于假定已验证的内部代码。

Playground link to code