我注意到以下行为:
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
,我没有编译错误。
事实上,在我的真实代码库中,我发现使用 cast 类型断言我有时会向对象文字添加完全错误的属性,但是在上面这样的简单案例中,我无法重现这种行为。
有人能解释一下这里发生了什么吗?
编辑:省略断言有效,谢谢@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
的实现。
答案 0 :(得分:2)
原因是您在这里使用type assertion。这基本上覆盖了所有打字稿类型检查。如果你删除 &LT;用户&gt; part - 编译器会给你预期的错误
编辑:
这就是你想要的:
interface User { name: string; }
function putUser<T extends User>(user:T):void { }
interface Musician extends User { instrument: string; }
putUser<Musician>({
name: "Bob Dylan"
});
答案 1 :(得分:1)
你做了一个类型断言。当您具有要接收的数据形状但没有自己的数据源时,您更愿意在与外部系统(如请求API)通信时使用类型断言。
打字稿类型断言很聪明。它不会让你做出完全错误的事情。这是一个例子:
interface Point {
x: number;
y: number;
}
function process(box: Point) {}
let empty = {};
let part = { x: 3 };
let full = { x: 3, y: 5 };
let vague = { x: 3, y: 5, z: 7 };
process(empty); //type mismatch, got {} expected {x, y}
process(part); //type mismatch, only {x} expected {x, y}
process(null); //no type mismatch, argument can be null
process(full); //full match
process(vague); //still works, but the function is not aware of "z" field.
process(<Point>empty); //assertion valid, object can be a Point instance
process(<Point>"123"); //wrong assertion, expected object instead of string
process(<Point>[]); //wrong assertion, expected object instead of array