Reputation: 43
I came across an issue I don't understand when using arrays of a custom type in typescript. I always assumed that you are only able to push a new object of the custom type into the array. However, pushing an object with additional fields seems possible if I define it beforehand.
Suppose I define a custom type:
type MyType = {
fieldOne: string,
fieldTwo: number,
};
These cases throw, IMO correct, TS errors (2322), since fieldThree
is not defined in my custom type:
const temp: MyType = { fieldOne: 'foo', fieldTwo: 2, fieldThree: 'whee'};
const tempArray: MyType[] = [{fieldOne: 'bar', fieldTwo: 2, fieldThree: 'whee'}];
const newArray: MyType[] = [];
newArray.push({fieldOne: 'bar', fieldTwo: 2, fieldThree: 'whee'});
Type '{ fieldOne: string; fieldTwo: number; fieldThree: string; }' is not assignable to type 'MyType'. Object literal may only specify known properties, and 'fieldThree' does not exist in type 'MyType'.(2322)
However, the following case with a generic, untyped object does not throw an error and allows me to push data
into the array:
const newArray: MyType[] = [];
const data = {fieldOne: 'bar', fieldTwo: 2, fieldThree: 'whee'};
newArray.push(data);
Am I wrong in assuming that the last case should also throw an error? What am I missing here?
Thanks!
Upvotes: 1
Views: 767
Reputation: 120480
This is explained in the documentation concerning excess property checking. Do take a moment to read it as it will shine a light on what is happening here.
In particular, pay attention to this section:
One final way to get around these checks, which might be a bit surprising, is to assign the object to another variable: Since squareOptions won’t undergo excess property checks, the compiler won’t give you an error.
Which explains the differences you are seeing. At this point, (loose) structural type compatibility is all that matters and incompatibility due to excess properties is ignored. The object is still known to walk like a duck and quack like a duck.
Upvotes: 1