I'm running into an issue with TypeScript whereby an object using one type can be injected via a destructing assignment into an another object that uses a completely different type, and TypeScript doesn't show any errors for it.
An example being:
interface Pizza {
cookingTime: number;
size: "Small" | "Medium" | "Large";
}
interface Car {
modelName: string;
yearManufactured: number;
}
const produceMalformedPizza = (car: Car): Pizza => {
return {
...car, // This is not a "Pizza" object but no errors are raised
cookingTime: 10,
size: "Small",
}
}
console.log(
produceMalformedPizza({
modelName: "NotAPizza",
yearManufactured: 1980
})
)
/* Output:
[LOG]: {
"modelName": "NotAPizza",
"yearManufactured": 1980,
"cookingTime": 10,
"size": "Small"
}
*/
I've tried to turn every possible strict flag on — and you can see it compiling online here.
If I try to return any specific properties in the produceMalformedPizza
function, then the compiler raises errors, as expected — but it seems as though I can inject arbitrary object data using a destructuring (spread) assignment.
I'm relatively new to TypeScript, so perhaps this is expected behaviour? I.e. I can't use object spread destructuring with inferred type safety?
Edit:
As per the answer from @T.J.Crowder this is intentional.
- There is some GitHub discussion about this issue specifically here: https://github.com/microsoft/TypeScript/issues/43499,
- And also a proposal to support "Exact" types here: https://github.com/microsoft/TypeScript/issues/12936
CodePudding user response:
It's expected behavior. The object you're returning is a subtype of Pizza
— it has all the properties Pizza
requires (plus some that it doesn't).
TypeScript does do "excess property checks" but only in limited situations. For instance, if you were to put a non-Pizza
property explicitly in that object literal, TypeScript would flag that up not because it's actually wrong from a type perspective (it's fine to use a subtype) but because it's probably a programmer mistake.
I'm slightly surprised it doesn't do that with ...car
(since car
has required properties), but it doesn't do excess property checks in all situations.