TypeScript function generic types intersection doe

2019-08-01 09:27发布

interface A {
  a: number;
}

let myVar: A = {
  a: 123
};

myVar = Object.assign({}, myVar, {
  b: 456
});

Why does TypeScript not complain about that re-assignment of myVar via the Object.assign() call?

Given that the type definition for that Object.assign() call is:

assign<T, U, V>(target: T, source1: U, source2: V): T & U & V;

...and the (return type) intersection of the three types in my call doesn't match interface A, shouldn't the compiler pick that up?

The problem is not related to TypeScript not being able to infer the types in the function call, because if I change the code to:

interface A {
  a: number;
}

interface B {
  b: number;
}

interface C {}

let myVar: A = {
  a: 345
};

myVar = Object.assign<C, A, B>({}, myVar, {
  b: 345
});

...it still doesn't complain.

I'm using TypeScript 2.2.1 and the "noImplicitAny" compiler flag is set to "true".

标签: typescript
2条回答
唯我独甜
2楼-- · 2019-08-01 09:59

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

Applying this rule to your example - A is compatible with A&B&C:

let abc:A&B&C = {a:123, b:456};

And assignment let a:A = abc; is perfectly valid.

More info here

查看更多
做自己的国王
3楼-- · 2019-08-01 10:09

A & B is assignable to X if A is assignable to X or B is assignable to X.

Given that TypeScript uses a structural type system, the reason there is no error is because the re-assignment of myVar gets the properties from the source/original myVar (second argument) and is satisfied from then on. So any other objects that get mixed in (e.g. first and third arguments), are irrelevant when it comes to satisfying the type of myVar.

Quote source

查看更多
登录 后发表回答