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

Typescript interface set type of property from another property from the same 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(或其数组)

的类型相同

TypeScript 中没有特定的具体类型与您认为有效的 argument 完全对应,其中 allowedValues 属性 必须与 [=14= 具有相同的类型] 属性。如果您希望能够在 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