我今天使用 TypeScript (v3.5.1) 遇到了一个奇怪的案例,这让我很困惑。我定义了一个带有可选属性的接口,但 TypeScript 允许我在使用对象解构时将默认值设置为我想要的任何值:
interface IFoo {
letter?: "a" | "b" | "c";
}
const foo: IFoo = {};
const { letter = 1 } = foo;
console.log(letter); // --> 1
// Type signature of `letter`: "a" | "b" | "c" | 1
// Why does TS modify the type to include 1?
在 TypeScript Playground 中运行此代码。
使用一些类型检查,我注意到 TypeScript 正在将
"a" | "b" | "c"
的预期签名修改为 "a" | "b" | "c" | 1
。当我尝试将 letter
默认为 1
时,我预计会出现类型错误。我在这里错过了什么吗?谢谢!
解构语句引入了一个新变量。它还没有类型,除非分配类型或在本例中推断类型。
查看向下编译的代码,这一点变得更加明显:
// const { letter = 1 } = foo;
var _a = foo.letter, letter = _a === void 0 ? 1 : _a;
或者稍微清理一下:
const letter = foo.letter === undefined ? 1 : foo.letter;
letter
是 foo.letter
或 1
(如果前者未定义)。
这是默认行为。如果你想防止这种情况发生并出现错误,你应该输入解构:
const { letter = 1 } : IFoo = foo; // "IFoo" added, this should show the error: Type '1' is not assignable to type '"a" | "b" | "c"'