如何将索引类型与交集类型组合

问题描述 投票:0回答:1

我正在尝试定义一个接受残余属性的类型,如下所示:

export type Base = {
  numberProperty: number;
  booleanProperty: boolean;
};

export type Residual = {
  [key: string]: string;
};

export type Complete = Base & Residual;

const abc: Complete = {
  numberProperty: 1234,
  booleanProperty: true,
  residualProperty: 'abc',
};

换句话说,我想确保numberPropertybooleanProperty分别始终为numberboolean类型,但其他任何属性都应为string。但是,在编译此版本(3.9.2)时,出现以下错误:

error TS2322: Type '{ numberProperty: number; booleanProperty: true; residualProperty: string; }' is not assignable to type 'Complete'.
  Type '{ numberProperty: number; booleanProperty: true; residualProperty: string; }' is not assignable to type 'Residual'.
    Property 'numberProperty' is incompatible with index signature.
      Type 'number' is not assignable to type 'string'.

13 const abc: Complete = {
         ~~~


Found 1 error.

我发现了类似的问题和解决类似问题的文档,但是我还没有找到有关如何执行此操作的最终答案。

typescript
1个回答
0
投票

问题是ResidualnumberProperty中的键booleanPropertyBase有冲突,因为它们不是字符串。

要修复它,您需要更改Residual以使除Base外的所有内容都是字符串。之后,Residual尊重Base,可以将它们组合在一起。

export type Base = {
  numberProperty: number;
  booleanProperty: boolean;
};

export type Residual = {
  [K in keyof any]: K extends keyof Base ? Base[K] : string;
};

export type Complete = Base | Residual;

const abc: Complete = {
  numberProperty: 1234,
  booleanProperty: true,
  residualProperty: 'abc',
};

如果无法更改Residual,则应重新考虑代码以避免它们的并集,因为它们存在冲突并且将是无效的。

const val1: Residual = {
  numberProperty: 'string', // valid, positive
};
const val2: Base = {
  numberProperty: 'string', // invalid, negative
};
const val3: Residual | Base = {
  numberProperty: 'string', // positive & negative = negative.
};

© www.soinside.com 2019 - 2024. All rights reserved.