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

Using structural typing and variable reassignment to bypass type checking on a function call with "named parameters"

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 } 在结构上 "fits into" {}.

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

是否应将其作为错误提交?

编辑 1

正如@shusson 指出的那样,这种行为(截至 v2.x)是预期的(由于权衡),即使它是不可取的。

有关问题根源的最相关讨论,请参阅 this GitHub issue and a 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);