[英]Mapped types: Make property required based on whether array of same object contains string literal
Is it possible to make an object property dependent on whether an array of the same object contains a string literal?是否可以根据相同 object 的数组是否包含字符串文字来制作 object 属性?
type Operator = "A" | "B"
type SomeStruct = {
operators: Operator[];
someProp: string; // this should be required if operators include "A", optional if not
}
// desired result
const structWithA: SomeStruct = {
operators: ["A", "B"],
someProp: "" // correct, since operators contains "A", someProp is required
};
const structWithB: SomeStruct = {
operators: ["B"],
// currently errors, but desired outcome is that it should not error, since operators does not contain "A"
};
declare const structs: SomeStruct[];
structs.map(struct => {
if(struct.operators.includes("A")) {
// someProp is safely accessible
}
// since .includes has a narrow type signature, maybe another way to safely access someProp is needed
})
By using an identity function to create your structs (and a predicate to discriminate its type), you can accomplish this:通过使用标识 function 来创建结构(以及区分其类型的谓词),您可以完成此操作:
type A = 'A';
type B = 'B';
type Operator = A | B;
type SomeStruct<T extends readonly Operator[]> = { operators: T; } & (
T extends readonly A[] ?
Record<'someProp', string>
: unknown
);
function craeteStruct <O extends readonly Operator[], T extends SomeStruct<O>>(struct: T): T {
return struct;
}
const structWithA = craeteStruct({
operators: ["A", "B"],
someProp: "",
});
const structWithB = craeteStruct({
operators: ["B"],
});
declare const structs: (SomeStruct<Operator[]>)[];
function includesA (struct: SomeStruct<Operator[]>): struct is SomeStruct<A[]> {
return struct.operators.includes('A');
}
structs.map(struct => {
if(includesA(struct)) {
struct.someProp; // string
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.