将扩展类型的对象分配给基类型

时间:2018-03-16 08:15:28

标签: typescript

我有这些接口:

interface BasicThing {
    someType: string
    property0: string
}
interface SpecificThing1 extends BasicThing {
    someType: 'special1'
    property1: number
}
interface SpecificThing2 extends BasicThing {
    someType: 'special2'
    color: string
}

在我的代码中我有这个变量

let myThing: BasicThing

稍后我会指定SpecificThing1SpecificThing2(或其他人)。

现在如果我要分配SpecificThing1,我可以这样做:

myThing = {
    someType:  'special1',
    property0: 'asdf',
    property1:  42
} as SpecificThing1

但是这样做,如果我为属性分配了错误的类型(例如property1: '42' // string is not compatible with number),我只会输入错误,但缺少属性根本没有提出任何错误:

myThing = {
    someType:  'special1',
    property0: 'asdf'
    // property1 is missing here, but no typing errors
} as SpecificThing1

解决这个问题的一种解决方法是:

myThing = ((): SpecificThing1 => {
    return {
        someType: 'special1',
        property0: 'asdf',
        // property1: 123 // Now we get the typing error: 'property1 is missing in type...'
    }
})()

但是这并不好看,为了获得该对象的正确类型而创建一个范围感觉不对。

是否可以在创建对象时为其分配类型,而不仅仅是在接收端?难道不可能以更优雅的方式做到这一点吗?

1 个答案:

答案 0 :(得分:1)

您可以使用联合类型而不是基本类型。效果几乎相同,您可以访问公共属性,这些属性是BaseThing中的属性(尽管如果派生类型具有它们,您可能会获得其他常见属性)

let d2: SpecificThing1 | SpecificThing2 = {
    someType: 'special1',
    property0: '0',
    property1: 1
}
let based: BasicThing = d2;

另一个解决方案是定义一个中间变量,而不是直接分配基类型的变量

let o: SpecificThing1 = {
    someType: 'special1',
    property0: '0',
    property1: 1
}, d: BasicThing = o;

另一种选择是定义辅助函数,您可以在其中指定泛型参数,并且将按预期执行检查:

const literal = <T>(o: T) => o;

let d: BasicThing = literal<SpecificThing1>({
    someType: 'special1',
    property0: '0',
    property1: 1
});
相关问题