gpt4 book ai didi

typescript 部分但不是完整的对象本身

转载 作者:行者123 更新时间:2023-12-04 08:04:24 26 4
gpt4 key购买 nike

假设我有一个对象:

type Obj = { a: string, b: string, c: string }

Partial<T> , TS 为您提供对象属性的所有可能组合,包括对象的完整形式。就我而言,我想排除完整对象(如果可能,也排除空对象)。

所以我想:

{} // ❌
{ a: string } // ✅
{ b: string } // ✅
{ c: string } // ✅
{ a: string, b: string } // ✅
{ a: string, c: string } // ✅
{ a: string, b: string, c: string } // ❌

我该怎么做?

最佳答案

要实现此行为,您需要为 Obj 类型创建两个约束。第一个应该排除“完整”类型,第二个应该排除“空”类型。


第一个约束意味着至少一个属性应该是undefined类型(或者根本不存在)。因此,我们需要一个类型联合,其中至少一个属性符合约束条件。

首先,我们必须映射初始类型以获得省略一个属性的所有可能的类型组合(注意 ? 修饰符 - 它确保允许可变数量的属性)并提取我们与 keyof T 的结合:

{
[ P in keyof T ] : {
[ K in Exclude<keyof T, P> ] ?: T[P]
}
}[keyof T]

如果我们保留它,我们仍然可以指定所有属性,因此我们需要明确告诉编译器不允许第三个属性。 ? 修饰符确保我们可以省略属性:

type NotAll<T> = {
[ P in keyof T ] : {
[ K in Exclude<keyof T, P> ] ?: T[P]
} & { [ M in P ] ?: never }
}[keyof T]

第二个约束意味着至少应该定义一个属性。逻辑几乎相同,但这次对于每个属性,我们都有一个所有属性的类型,除了一个设置为可选的与需要此属性的类型相交:

type AtLeastOne<T> = {
[ P in keyof T ] : {
[ K in Exclude<keyof T, P> ] ?: T[P]
} & { [ M in P ] : T[M] }
}[keyof T];

最后,我们需要将第二个约束与第一个结合起来。由于第一个约束为我们提供了允许类型的联合,AtLeastOne 应该应用于联合的每个成员:

type NotAll<T> = {
[ P in keyof T ] : AtLeastOne<{
[ K in Exclude<keyof T, P> ] : T[P] //note the modifier is moved to `AtLeastOne`
}> & { [ M in P ] ?: never }
}[keyof T];

就是这样,让我们​​测试一下我们的类型:

type test = NotAll<Obj>;

const empty : test = {}; //error
const a : test = { a: "test" }; //OK
const ab : test = { a: "test", b: "test" }; //OK
const bc : test = { b: "test", c: "test" }; //OK
const abc : test = { a: "test", b : "test", c: "test" }; //error

Playground

关于 typescript 部分但不是完整的对象本身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66300983/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com