Reputation: 111
I am reading Typescript handbook, in the chapter of interface, I found a question:
interface LabelledValue {
label: string;
}
function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
The printLabel
need an object with a label:string
property, but the object we passed has another property called size
. It is OK cause the compiler only checks that at least the ones required are present and match the types required.
But, we I call printLabel
in this way:
printLabel({size: 10, label: "Size 10 Object"});
The compile throws an exception.
so why?
Upvotes: 3
Views: 603
Reputation: 23483
The documentation is outdated and an issue exists to fix it.
From the What's New in TypeScript page:
TypeScript 1.6 enforces stricter object literal assignment checks for the purpose of catching excess or misspelled properties. Specifically, when a fresh object literal is assigned to a variable or passed as an argument for a non-empty target type, it is an error for the object literal to specify properties that don't exist in the target type.
The idea is that it's a very common pattern is to pass in an object literal as a bag of options. For instance:
interface ConnectionOptions {
tryHttps?: boolean;
url?: string;
username?: string;
password?: string;
}
But all of those properties are optional. Before 1.6, I could misspell any of them and the compiler would never catch this error:
declare function connect(options: ConnectionOptions);
// Notice the property given is 'tryHTTPS' instead of 'tryHttps'.
connect({ url: "stackoverflow.com", tryHTTPS: true });
You can always get around this by adding a type assertion to the type you're assigning to:
printLabel({size: 10, label: "Size 10 Object"} as LabelledValue);
// or...
printLabel(<LabelledValue>{size: 10, label: "Size 10 Object"});
Upvotes: 4