Why is there a difference between passing a variable assigned to an object literal as an argument(let x = {color: 'red', width: 200}
), and passing an object literal as an argument ({color: 'red', width: 200}
)?
In other words, the value of the argument is the same ({color: 'red', width: 200}
).
So why does the compiler do excess checking when the object is passed, and "regular shape" checking when variable assigned to that object is passed ?
Think about the function type signature:
type SOME_OBJECT = {
propA: TYPE_A,
propB: TYPE_B
}
function foo(obj: SOME_OBJECT) {
// WILL DO SOMETHING WITH obj
}
In the example above, function foo
is expecting an object obj
that has a propA
of type TYPE_A
and a propB
of type TYPE_B
. As long as something meets those requirements, function foo
will be able to do its thing. Or at least, that is what its contract is implying. So what should it excess property check the obj
parameter?
Now let's assign an object literal. Let's say you have a type that has an optional parameter maybe
.
interface SOME_OBJECT_WITH_OPTIONAL {
color: string,
width: number,
maybe?: boolean
}
const x1: SOME_OBJECT_WITH_OPTIONAL = {
color: "red",
width: 200,
mayeb: true // <--- TS ERROR HERE - EXCESS PROPERTY CHECKING IS REALLY IMPORTANT
}
See that you've misspelled that maybe
property as mayeb
. Thanks to the excess property checking, Typescript warns you that you've made that mistake. Can you imagine the pain if this was not handled like it is? In our example, no property would be missing, since maybe
is optional, so it's allowed to be missing. You would get no errors or warnings whatsoever.
A function that expects an obj
of type SOME_OBJECT_WITH_OBJECT
still won't mind. Because all the required properties color
and width
are present.
You can read more about this subject here:
Typescrip Docs - Excess Property Checks
Medium - Introduction to TypeScript Interfaces — Object Literals and Function Types