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".
Applying this rule to your example -
A
is compatible withA&B&C
:And assignment
let a:A = abc;
is perfectly valid.More info here
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/originalmyVar
(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 ofmyVar
.Quote source