【发布时间】:2016-06-21 14:51:20
【问题描述】:
我注意到以下行为:
interface User {
name: string;
age: number;
}
let user:User = {
name: "Aaron",
age: 99
}
如果我省略age: 99,我会得到一个编译错误。 这是我所期望的行为。
但是:
function putUser(user:User):void { }
putUser(<User> {
name: "Aaron"
});
我没有因为缺少非可选属性 age 而出现编译错误。
事实上,在我的真实代码库中,我发现使用 casting type assertion 我有时可以向对象字面量添加完全错误的属性,但我'无法在上述简单情况下重现此行为。
谁能解释这里发生了什么?
编辑:省略断言有效,感谢@Amid。但是,我遇到的问题是在这种情况下:
interface User { name: string; }
function putUser(user:User):void { }
interface Musician extends User { instrument: string; }
putUser(<Musician> {
name: "Bob Dylan"
});
问题是我想验证Musician 对象,但putUser 只需要基本User 对象。我认为类型断言会给我更好的类型安全性,但在这种情况下它实际上降低了类型安全性。
编辑#2
看起来我可以使用泛型类型约束得到我想要的,实际上 看起来 非常像我的类型断言:
function putUser<T extends User>(user:T):void { }
putUser<Musician>({
name: "Bob Dylan",
instrument: "Guitar"
});
在这种情况下,它似乎会确保对象字面量完全是 Musician 的实现。
【问题讨论】:
-
查看规范,
<User>obj不是演员表,而是obj具有User类型的断言。运行时不检查类型断言,请参阅here -
是的,你说得对,我称它为演员表,但这是一个断言……那么,有没有“真正的”演员表?
-
这是documented 绕过“严格的对象字面量赋值检查”的方法之一。
-
检查我更新的答案。我认为它显示了如何获得您想要实现的目标。
-
哇,我应该等你的回答,我刚刚对我的问题进行了同样的编辑。 :) 谢谢,你真的把它清理干净了。
标签: typescript