Typescript字符串字面量与鸭子类型对象

10

Typescript 1.8引入了字符串字面量类型。然而,在将对象作为参数传递时,例如以下情况:

const test = {
    a: "hi",
    b: "hi",
    c: "hi"
};

interface ITest {
    a: "hi" | "bye"
}

function testFunc (t: ITest) {

}

testFunc(test);

出现以下错误:

类型为'{ a: string; b: string; c: string; }'的参数无法分配给类型为'ITest'的参数。 属性'a'的类型不兼容。 类型'string'无法分配给类型'"hi" | "bye"'。 类型'string'无法分配给类型'"bye"'。

我原本以为这个代码符合接口要求,但可能是我的疏忽。


在测试中,a、b和c是字符串类型,而在您的接口中是“hi”|“bye”类型。 - nullforce
这很有道理,尽管有点违反直觉。谢谢。 - Alexander Mattoni
1个回答

13
test.a的类型被推断为string而不是"hi"。编译器比较的是类型而不是最初的字符串表达式。
为了使其正常工作,您需要将该属性类型定义为"hi" | "bye"
type HiBye = "hi" | "bye";

const test = {
    a: "hi" as HiBye,
    b: "hi",
    c: "hi"
};

interface ITest {
    a: HiBye
}

function testFunc (t: ITest) {
}

testFunc(test);

请注意,原始情况下编译器无法推断 test.a 的类型为 "hi",因为在达到 testFunc(test) 之前您可以将不同的值赋给 test.a ——例如 test.a = "not hi"
顺便说一句:编译器不会将字符串表达式推断为常量字符串变量的类型,这也会导致许多麻烦……想象一下这种情况。
const myVariableTypedAsHi = "hi";   // implicitly typed as "hi"
let otherVar = myVariableTypedAsHi; // otherVar implicitly typed as "hi"

otherVar = "test"; // error: cannot assign `"test"` to `"hi"`—well that would be annoying

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接