扩展多个接口的更好方法

Better way of extending multiple interfaces

晚上好,

只是一个快速的,我不是很擅长打字稿,但仍在寻找我的泛型方法。 肯定有更简洁的方法来执行以下操作,在这种情况下最佳做法是什么?

export interface Fruit {
  colour: string;
  age: number;
  edible: boolean;
}

export interface A {
  Apple: Fruit[];
  Banana: Fruit[];
  Peach: Fruit[];
  Plum: Fruit[];
  Melon: Fruit[];
}

export interface B {
  diffApple: Fruit[];
  diffBanana: Fruit[];
  diffPeach: Fruit[];
  diffPlum: Fruit[];
  diffMelon: Fruit[];
}

export interface FruitIndex
  extends A, B, (etc)

我有这种情况,但是对于多个接口,它看起来真的很乱。 TIA

我希望“整洁”、“整洁”、“干净”是仁者见仁智者见智。您可以重构 AB 的定义以减少冗余。对于 A:

export type A = Record<"Apple" | "Banana" | "Peach" | "Plum" | "Melon", Fruit[]>;

这里我们使用 the Record<K, T> utility type, a mapped type,它为联合 K 中的每个键提供相同的 属性 值类型 T。您可以验证类型是否符合您的预期:

/* type A = {
    Apple: Fruit[];
    Banana: Fruit[];
    Peach: Fruit[];
    Plum: Fruit[];
    Melon: Fruit[];
} */

然后输入 B:

export type B = { [K in keyof A as `diff${K}`]: A[K] }

这里我们使用 key remapping in mapped types along with template literal types"diff" 添加到 A 的所有键之前,同时保持值相同。同样,您可以验证类型是否符合您的预期:

/* type B = {
    diffApple: Fruit[];
    diffBanana: Fruit[];
    diffPeach: Fruit[];
    diffPlum: Fruit[];
    diffMelon: Fruit[];
} */

这段代码比你原来的AB版本更简洁...但我不知道它是否更“整洁”。对于非专家也能理解的代码,有话要说。看 { [K in keyof A as `diff${K}`]: A[K] } 的人如果不知道这意味着什么,可能不会将其描述为“干净”。


对于您的 FruitIndex,我看不出有什么方法可以使它更简洁;在某个地方,您需要列出您希望扩展的所有父接口。您可以在此处的 extends 一词之后执行此操作,也可以创建一些其他结构来列出它并从中计算 FruitIndex 。无论哪种方式,您都会在某个地方第二次输入 AB。所以我会保持原样,至少对于这个例子:

export interface FruitIndex extends A, B { }

Playground link to code