typescript - 使用结构类型和变量重新分配来绕过对带有 "named parameters"的函数调用的类型检查

标签 typescript typescript2.0

function myFunc({ param1 }: {                                                
  param1: number;                                                            
}) {                                                                         
  // param1 is marked as mandatory in the definition, but we can bypass that 
}                                                                            

const mismatchedFunc: ({}) => void = myFunc;                                 

mismatchedFunc({}); // No compile-time error

我猜测这种行为的原因源于 TypeScript 的结构类型性质,因为 { param1: number } 在结构上“适合” {}.

然而,这不是不良行为(在这种特定情况下,或一类情况下),因为它在很大程度上绕过了 TypeScript 提供的类型检查吗?

这应该作为错误提交吗?

编辑 1

正如@shusson 指出的那样,这种行为(从 v2.x 开始)是预期的(由于权衡),即使它是不受欢迎的。

有关问题根源的最相关讨论,请参阅 this GitHub issue和一个 follow-up proposal尝试解决它。​​

最佳答案

这里有两件事:

  1. structural typing

    The basic rule for TypeScript’s structural type system is that x is compatible with y if y has at least the same members as x.

  2. bivariant function parameters

    When comparing the types of function parameters, assignment succeeds if either the source parameter is assignable to the target parameter, or vice versa

例子:

type t1 = { param1: number };
type t2 = { };

let f1 = (a: t1) => {};

let f2: (a: t2) => void = f1; // bivariant assignment

let x: t1 = { param1: 1 };
let y: t2 = {};

y = x; // because of this, f1 is assignable to f2 through bivariant assignment
x = y; // compile error

f1(x);
f1(y); // compile error

f2(x);
f2(y);

关于typescript - 使用结构类型和变量重新分配来绕过对带有 "named parameters"的函数调用的类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43219592/

相关文章:

javascript - typescript 通过将具有相同键的对象的值组合来合并 2 个对象数组

angular - 在 Angular 2 中将函数从父组件传递到子组件

angular - RxJS 6+ 类型 'Observable' 必须有一个返回迭代器的 'Symbol.iterator' 方法

typescript - 如何定义 TS 类型/接口(interface)等。哪个可以通过多个文件访问?

angular - Angular 模板中的可选链接

typescript - 将(非嵌套)对象数组转换为具有完整类型的数组对象

angular - 单击按钮时如何展开/折叠 Accordion 选项卡?

typescript - 如何让 VSCode 加载 NPM 依赖项的源映射?

typescript - Tslint - 忽略包含字符串 : "spec"? 的文件