【问题标题】:Type assertion vs properties类型断言与属性
【发布时间】: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 的实现。

【问题讨论】:

  • 查看规范,&lt;User&gt;obj 不是演员表,而是obj 具有User 类型的断言。运行时不检查类型断言,请参阅here
  • 是的,你说得对,我称它为演员表,但这是一个断言……那么,有没有“真正的”演员表?
  • 这是documented 绕过“严格的对象字面量赋值检查”的方法之一。
  • 检查我更新的答案。我认为它显示了如何获得您想要实现的目标。
  • 哇,我应该等你的回答,我刚刚对我的问题进行了同样的编辑。 :) 谢谢,你真的把它清理干净了。

标签: typescript


【解决方案1】:

原因是你在这里使用type assertion。这基本上覆盖了所有打字稿类型检查。如果你删除 部分 - 编译器会给你你期望的错误

编辑:

这就是你想要的:

interface User { name: string; }

function putUser<T extends User>(user:T):void { }

interface Musician extends User { instrument: string; }

putUser<Musician>({
    name: "Bob Dylan"
});

【讨论】:

    【解决方案2】:

    你做了一个类型断言。当您拥有要接收的数据形状但没有自己的数据来源时,您更愿意在与外部系统通信(如请求 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 
    

    【讨论】:

      猜你喜欢
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 2018-09-21
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多