【问题标题】:Why can I assign unknown properties to literal object in typescript?为什么我可以将未知属性分配给打字稿中的文字对象?
【发布时间】:2020-07-21 01:10:04
【问题描述】:
  type ExpectedType = Array<{ name: number, gender?: string }>

  function go1(p: ExpectedType) {

  }  

  function f() {
    const a = [{name: 1, age: 2}]
    go1(a)                   // doesn't complain
    go1([{name: 1, age: 2}]) // complain 'Object literal may only specify known...'
    go1(['no matter'].map(n => ({name: 1, age: 2}))) // doesn't complain
  }

打字稿代码如上,我的问题是最后三行不一样吗?为什么第一行可以通过,第二行投诉,第三行通过?

也在打字稿操场上: playground

【问题讨论】:

  • 这是一个有趣的问题。看起来const a = [{name: 1, age: 2}] as ExpectedType 会抱怨,但为什么要强制转换类型,我不知道。
  • 什么版本的打字稿,它在哪里抱怨? IDE?吴服?构建?别的地方?根据您的版本,a 被输入为any,这是允许的。
  • @cjd82187 我在 TypeScript 操场上尝试了最新版本,结果是一样的typescriptlang.org/play/…

标签: javascript reactjs angular typescript


【解决方案1】:

当将 var a 赋值给 go1() 的参数时,似乎将变量 a 赋值给另一个 para 变量。在这种情况下,因为 a 的类型与参数变量类型兼容。但是如果你把type改成{name:number,gender:string},还是会出现类型错误。

在将字面量对象作为参数赋值时,这种情况下没有类型转换,因此编译器可以检测到这种类型错误。

更多详情请参考here

TypeScript 结构类型系统的基本规则是 x 是 如果 y 至少具有与 x 相同的成员,则与 y 兼容。为了 示例:

interface Named {
    name: string;
}

let x: Named;
// y's inferred type is { name: string; location: string; }
let y = { name: "Alice", location: "Seattle" };
x = y;

要检查是否可以将 y 分配给 x,编译器会检查每个 x 的属性以在 y 中找到对应的兼容属性。在 在这种情况下, y 必须有一个名为 name 的成员,它是一个字符串。它确实, 因此允许分配。

【讨论】:

  • 感谢您的精彩解释,我编辑了问题并在最后一行添加了另一个go1(['no matter'].map(n =&gt; ({name: 1, age: 2}))),据我了解这也是一个字面情况,为什么这一行没有投诉?
  • 希望对您有所帮助。github.com/Microsoft/TypeScript/issues/3755
【解决方案2】:

经过一番研究,我发现答案在 TypeScript 的文档中。

所以最后 3 行之间的区别在于: 第 2 行中的参数是字面意义上的对象,而其他 2 行不是,TypeScript 以不同的方式对待字面参数和非字面参数:

Excess Property Checks

【讨论】:

    猜你喜欢
    • 2022-10-13
    • 2014-06-11
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多