Typescript接口的可选属性,取决于其他属性

时间:2018-07-19 00:58:43

标签: javascript typescript

假设我们具有以下打字稿界面:

interface Sample {
    key1: boolean;
    key2?: string;
    key3?: number;
};

在这种情况下,key1始终是必需的,key2始终是可选的,而如果key1为true,则key3应该存在,而如果key1为false,则key3应该不存在。换句话说,一个键的出现取决于另一个键的值。我们如何在打字稿中实现这一目标?

3 个答案:

答案 0 :(得分:13)

最简单的表示方法是使用type alias而不是接口:

type Sample = {
  key1: true,
  key2?: string,
  key3: number
} | {
  key1: false,
  key2?: string,
  key3?: never
}

在这种情况下,类型别名是您要描述的两种类型的union。因此,Sample应该是第一个组成部分(其中key1为真,并且需要key3)或第二个组成部分(其中key1为假,而key3缺)。

类型别名类似于接口,但是它们不能完全互换。如果使用类型别名导致某种错误,请在问题中添加有关您的用例的更多详细信息。

希望有帮助。祝好运!

答案 1 :(得分:0)

我想在这里提到另一种不错的方法是使用有区别的联合:

enum ShapeKind {
    Circle,
    Square,
}

interface Circle {
    kind: ShapeKind.Circle;
    radius: number;
}

interface Square {
    kind: ShapeKind.Square;
    sideLength: number;
}

let c: Circle = {
    kind: ShapeKind.Square,
    //    ~~~~~~~~~~~~~~~~ Error!
    radius: 100,
}

如Typescript文档中所述: https://www.typescriptlang.org/docs/handbook/enums.html#union-enums-and-enum-member-types

答案 2 :(得分:0)

我认为可读的解决方案是使用overload

所以我们可以这样做:

type IOverload = {
  (param: { arg1: number }): any;
  (param: { arg1: number; arg2: string; arg3: number }): any;
};

const sample: IOverload = (args) => {...};

sample({ arg1: 1, arg2: 'a' });

===> Property 'arg3' is missing in type '{ arg1: number; arg2: string; }' but required 
in type '{ arg1: number; arg2: string; arg3: number; }'.