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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With