[英]Typescript interface optional properties depending on other property
Let's say we have the following Typescript interface
:假设我们有以下 Typescript interface
:
interface Sample {
key1: boolean;
key2?: string;
key3?: number;
};
In this case, key1
is always required, key2
is always optional, while key3 should exist if key1
is true
and should not exist if key1
is false
.在这种情况下, key1
始终是必需的, key2
始终是可选的,而如果key1
为true
,则 key3 应该存在,如果key1
为false
则不应该存在。 In another word, a key's occurrence depends on another key's value.换句话说,一个键的出现取决于另一个键的值。 How can we achieve this in Typescript?我们如何在 Typescript 中实现这一点?
The most straightforward way to represent this is with a type alias instead of an interface:最直接的表示方法是使用类型别名而不是接口:
type Sample = {
key1: true,
key2?: string,
key3: number
} | {
key1: false,
key2?: string,
key3?: never
}
In this case the type alias is the union of two types you're describing.在这种情况下,类型别名是您所描述的两种类型的联合。 So a Sample
should be either the first constituent (where key1
is true and key3
is required) or the second constituent (where key1
is false and key3
is absent).因此, Sample
应该是第一个成分(其中key1
为 true 且需要key3
)或第二个成分(其中key1
为 false 且key3
不存在)。
Type aliases are similar to interfaces but they are not completely interchangeable.类型别名类似于接口,但它们不能完全互换。 If using a type alias leads to some kind of error, please add more detail about your use case in the question.如果使用类型别名导致某种错误,请在问题中添加有关您的用例的更多详细信息。
Hope that helps.希望有帮助。 Good luck!祝你好运!
Thought I'd mention another nice approach here could be to use a discriminated union:以为我会在这里提到另一种不错的方法是使用受歧视的联合:
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,
}
As described in the Typescript docs: https://www.typescriptlang.org/docs/handbook/enums.html#union-enums-and-enum-member-types如 Typescript 文档中所述: https ://www.typescriptlang.org/docs/handbook/enums.html#union-enums-and-enum-member-types
I think that a readable solution is to use overload我认为一个可读的解决方案是使用重载
so we can do this:所以我们可以这样做:
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; }'.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.