我想为可能具有属性“a”或“b”的对象声明一个接口
interface myInterface {
a ?: string;
b ?: string;
}
Run Code Online (Sandbox Code Playgroud)
使 a 和 b 都是可选的。我想要类似的东西
interface myInterface {
a|b ?: string;
}
Run Code Online (Sandbox Code Playgroud)
(编辑1)扩展案例
interface myInterface
{
mustHaveProp1 : number;
a|b : string;
mustHaveProp2 : string;
b|d|e : number;
}
Run Code Online (Sandbox Code Playgroud)
你不能用接口来做到这一点,你可以用联合来做到这一点。这个想法是生成一个联合,其中每个联合组成部分都具有与原始类型相同的属性,但需要一个属性,因此myInterface我们需要类似:{ a: string, b?: string } | { a?: string, b: string }。
上面的并集也(大部分)相当于下面的交集myInterface & ({ a : string } | { b: string }。&(如果我们在和之间应用分配属性,|我们将得到(myInterface & { a: string }) | ((myInterface & { b: string }),并且由于在每个交集中,属性都显示为可选和必需的,因此必需的属性胜出)。
那么最大的问题就变成了如何从myInterface不需要明确写出来的情况下创建这个联合。为此,我们可以使用映射类型从原始类型中获取每个属性,创建每个成员组成部分,然后索引该类型以获得所有这些新类型的并集。然后我们可以与原始类型相交:
interface myInterface {
a?: string;
b?: string;
}
type OneProp<T> = {
[P in keyof T]-?: Record<P, T[P]>
}[keyof T]
type RequireAtLeastOne<T> = T & OneProp<T>
let o1: RequireAtLeastOne<myInterface> = {} // err no properties
let o2: RequireAtLeastOne<myInterface> = { a: "" } // a present, ok
let o3: RequireAtLeastOne<myInterface> = { b: "" } // b present, ok
let o4: RequireAtLeastOne<myInterface> = { a: "", b: "" } // a and b present, ok
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
717 次 |
| 最近记录: |