键入断言与属性

时间:2016-03-07 21:15:30

标签: typescript

我注意到以下行为:

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的实现。

2 个答案:

答案 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