I'd like to assert that a type can have neither, either, but not both of a pair of properties.
The following does not work, although I'd have assumed it would. Apparently having a: never and b: never means that I have to provide both?
I also tried using {} in place of NeitherANorB which compiled and ran, but did not catch the fourth case where I incorrectly passed both options.
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
Run Code Online (Sandbox Code Playgroud)
kay*_*ya3 13
您可以使用{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'};
Run Code Online (Sandbox Code Playgroud)
为了方便起见,这里有一个用于构造这样的联合的辅助类型,其中最多允许使用某些属性之一:
// 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}>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2736 次 |
| 最近记录: |