用于限制赋值的Typescript类型

时间:2017-04-10 11:55:15

标签: typescript union-types

假设:

interface B {
    base: string;
}
interface C1 extends B {
    c1: string;
}
interface C2 extends B {
    c2: string;
}

type A = C1 | C2;

var aOk1: A = {
    base: '',
    c1: '',
}
var aOk2: A = {
    base: '',
    c2: '',
}
var a: A = {
    base: '',
    c1: '', // was expecting this to error at compile time
    c2: '', // was expecting this to error at compile time
}

a.c1; // Correctly errors
a.c2; // Correctly errors

正如代码中标记的那样,我期望分配c1c2属性导致编译时错误。有没有办法实现这个目标?

为了澄清动机,这是因为设置选项对象有两种相互排斥的方式,我希望使用以下方法在定义(.d.ts)文件中键入它: / p>

// definition in a .d.ts file
someFunction(options: C1 | C2)

因此,如果有人试图错误地传递两个值设置的选项对象,它们将在编译时显示错误,但是他们当前可以执行以下操作而不会出现任何编译时错误:

// consuming in a .ts file

// User might think both options will be used but
// actually c2 option silently overrides c1.
someFunction({base: '', c1: '', c2: ''});  

** 编辑:标记的联合类型 **

您无法使用tagged union types也称为"Discriminated Unions"解决此问题:

interface C1 extends B {
    kind: 'C1',
    c1: string;
}
interface C2 extends B {
    kind: 'C2',
    c2: string;
}

type A = C1 | C2;

var a: A = {
    kind: 'C1',
    base: '',
    c1: '', // would like this to compile time error
    c2: '', // would like this to compile time error
};