使用鸭子类型的对象键入字符串文字

Typescript string literal with duck-typed object

本文关键字:字符串 文字 对象 鸭子 类型      更新时间:2024-01-03

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:sstring;c:string!}"的参数不可分配给类型为"ITest"的参数。属性"a"的类型不兼容。类型"string"不可分配给类型"hi"|"bye"。类型"string"不可分配给类型"bye"。

我希望它能工作,因为它符合接口的要求,但我可能忽略了一些东西。

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"是没有意义的,因为您可以在test.a到达testFunc(test)-ex。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