typescript - 打字稿既不是,也不是,但不是两个属性
问题描述
我想断言一个类型既不能有,也不能有,但不能同时有一对属性。
以下内容不起作用,尽管我认为它会起作用。显然拥有a: never
并且b: never
意味着我必须同时提供这两者?
我还尝试使用{}
已编译并运行的 NothingANorB 代替,但没有发现我错误地传递了两个选项的第四种情况。
interface JustA {
a: string;
b: never;
}
interface JustB {
a: never;
b: string;
}
interface NeitherANorB {
a: never;
b: never;
}
type NotBothAAndB = JustA | JustB | NeitherANorB;
function testMe(x: NotBothAAndB) {
console.log(x);
}
testMe({}); // OK
testMe({ a: "HI!" }); // OK
testMe({ b: "SUP?" }); // OK
testMe({ a: "HI!", b: "SUP?" }); // NOT OK
解决方案
您可以使用{property?: never}
或{property?: undefined}
说属性不应该存在。请注意,即使在前一种情况下,只要属性具有 value ,它就允许存在undefined
,因为这正是 Typescript 处理可选属性的方式。所以这应该做你想要的:
type NotBoth =
| {a: string, b?: never}
| {a?: never, b: string}
| {a?: never, b?: never}
// ok
const test1: NotBoth = {a: 'foo'};
const test2: NotBoth = {b: 'bar'};
const test3: NotBoth = {};
// error: 'string' is not assignable to 'undefined'
const testFail: NotBoth = {a: 'foo', b: 'bar'};
为方便起见,这里有一个辅助类型,用于构造这样的联合,其中最多允许一些属性之一:
// Simplify<T> just makes the resulting types more readable
type Simplify<T> = T extends infer S ? {[K in keyof S]: S[K]} : never
type NoneOf<T> = Simplify<{[K in keyof T]?: never}>
type AtMostOneOf<T> =
| NoneOf<T>
| {[K in keyof T]: Simplify<Pick<T, K> & NoneOf<Omit<T, K>>>}[keyof T]
type NotBoth = AtMostOneOf<{a: string, b: string}>
推荐阅读
- mongodb - MongoDB基于共享键聚合多个对象数组
- pyspark - 基于 PySpark 中另一个数据帧的值,使用 ArrayType 映射列的值
- javascript - 不能使用点符号或括号符号进入数组
- linux - Kafka 将 Docker 用于生产集群
- ios - 如果在同一个队列上调度会发生什么?
- python - 列表压缩奇怪的行为
- python - pysnmp 如何使用传入陷阱的 varBinds 内容转发新陷阱?
- imageview - 为什么 VkImageView 格式与底层 VkImage 格式不同?
- javascript - 如何在 Javascript 中生成加密安全的伪随机数?
- python - Python 中的 Lambda 表达式