typescript - 通用函数允许任意键

标签 typescript

为什么下面的代码可以编译成功?由于 bar 不是 MyState 的一部分,我预计它会生成编译器错误。

type MyState = { foo: number; };
type Reducer<T> = (state: T) => T;

const wtf: Reducer<MyState> = (state) => {
  return { foo: 123, bar: 123 }; // `bar` isn't part of MyState
};

最佳答案

crashmstr 的答案是正确的,但值得解释为什么这种情况与您确实遇到错误的情况不同。

对象字面量只会在特定情况下导致额外的属性错误。

在这种情况下:

var x: MyState = { foo: 10, bar: 20 };

类型系统执行以下步骤:

  • 检查 MyState 是否是有效类型(它是)
  • 检查初始化程序是否有效:
    • 初始化器的类型是什么?
      • 它是新鲜对象类型{foo: 10, bar: 20}
    • 是否可以分配给 MyState
      • 是否有 foo 属性?
      • 它的类型匹配吗?
        • 是(10 -> number)
      • 是否有来自新类型的任何额外属性?
        • 是的
          • 错误

这里的关键是新鲜度。如果来自对象字面量的类型直接来自对象字面量本身,则它是新鲜的。这意味着两者之间存在差异

// Error
var x: MyState = { foo: 10, bar: 20 };

// OK
var x1 = { foo: 10, bar: 20 };
var x2: MyState = x1;

因为一旦对象字面量被分配到 x1 中,它的新鲜度就消失了。

您的示例遭遇同样的命运 - 一旦对象文字成为函数返回类型的一部分,它的新鲜度就消失了。这也解释了如果函数表达式上有返回类型注释,为什么会再次出现错误。

关于typescript - 通用函数允许任意键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45868086/

相关文章:

typescript - 如何使用 Typescript 在 vuejs 中创建功能组件

html - 如何在 Angular 4 中为 ng-template 标签提供样式?

typescript - 一行 typescript 语法是如何工作的

javascript - 如何使用 Q 保留对 promise 链的响应

html - 如何使用 *ngFor 显示数据

typescript - Vue 组件和 TypeScript 的状态问题

Angular 2(2.0.0 到 2.2.0~)在使用 "import ' 反射元数据行添加自定义装饰器时出错”

typescript - 类型“IntrinsicAttributes”上不存在 activeStyle

angular - 如何在新标签页中打开Angular组件?

javascript - 正则表达式是什么,首先是带有逗号的数值,然后是带有空格的字符串(例如 - 20,000 值)?