Using structured typing and variable reassignment to test the type of traversal for 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

      

I assume the reason for this behavior stems from the structural nature of TypeScript, as it is { param1: number }

structurally "fit in" {}

.

That said, isn't this undesirable behavior (in this particular case or class of cases) because it largely bypasses the type checking that TypeScript provides?

Should it be filed as a bug?

Edit 1

As @shusson pointed out, the behavior is expected (versus v2.x) (due to tradeoff), although not desirable.

For the most relevant discussion about the roots of the problem, see this GitHub issue and the following suggestion to try and address it.

+3


source to share


1 answer


There are two things here:

  • structural typing

    The basic rule of TypeScript's structured type system is that x is compatible with y if y has at least the same elements as x.

  • bivariant function parameters

    When comparing functional parameter types, assignment succeeds if either the source parameter is assigned to the target parameter, or vice versa



Example:

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);

      

+2


source







All Articles