Search code examples
typescripttypecheckingobject-literal

Typescript: Why is there a difference between passing an object and a variable assigned to that object as an argument?


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 ?


Solution

  • 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
    }
    

    Typescript playground

    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.

    enter image description here

    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.

    enter image description here

    You can read more about this subject here:

    Typescrip Docs - Excess Property Checks

    Medium - Introduction to TypeScript Interfaces — Object Literals and Function Types