Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discrepancy between passing named object and anonymous object in type check

Tags:

typescript

Consider the following code

interface Config {
    label?: string;
    width?: number;
}

function printLabel(labelledObj: Config) {
    console.log(labelledObj.label);
}

let myObj = {not_in_interface: 10, label: "Size 10 Object"};

// No error
printLabel(myObj);

// Will run into error  Argument of type '{ not_in_interface: number; label: string; }' is not assignable to parameter of type 'Config'
printLabel({not_in_interface: 10, label: "Size 10 Object"});

What is the reason for the discrepancy?

It seems like anonymous object triggers excess property checking while named object does not.

like image 760
Jal Avatar asked Dec 20 '25 15:12

Jal


1 Answers

TypeScript only checks for excess properties at the location an object literal is declared (as you stated in your question). The TypeScript docs describe this check: (Also feel free to check out the full spec here.)

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.

So why this behavior? In short, in some use cases you'd want to allow extra properties when passing around objects, and in other use cases you wouldn't. For example, it'd be sad if our printWeightInPounds function below didn't accept our Dog object:

interface Animal { weight: number; }
interface Dog extends Animal { breed: string; }

const myDog: Dog = { weight: 100, breed: "Poodle" }; // a big poodle!
printWeightInPounds(myDog);

Being strict and not allowing extra properties in all cases would disallow a lot of legitimate code. However, opt-in strictness could be a good thing in some places. There are proposals to have an "Exact type" feature which would allow you to opt-in to only passing identical types around. It's still in discussion though.

like image 63
JKillian Avatar answered Dec 24 '25 11:12

JKillian