2

Here I get an error which I understand

interface Animal {
  name:string
}

interface Human{
  firstName:string
}

let test = (param: Animal )=>{
  if("name" in param)
   return param.name

  return param.firstName
}

console.log(test({name:"1", firstName:"2"}))

because Animal doesn't have firstName.

As soon as I modify that function to

let test = (param: Animal | Human)=>{
  if("name" in param)
   return param.name

  return param.firstName
}

the error is gone. But I am confused. Doesn't | mean that the param is either Animal or Human? But {name:"1", firstName:"2"} is neither isn't it? (Like in the first example TS wasn't accepting this as an Animal).


Bonus question also from the docs it says here it is not an error

    interface Pet {
      name: string;
    }
    let pet: Pet;
    // dog's inferred type is { name: string; owner: string; }
    let dog = { name: "Lassie", owner: "Rudd Weatherwax" };
    pet = dog;

because dog has more properties than a Pet. But why did it complain in my initial case when I passed the object as Animal? it had more properties, isn't it?

  • Object types aren't closed, so `{name: string, firstName: string}` is both an `Animal` and a `Hunan`. Unions aren't exclusive, so `Animal & Human` is assignable to `Animal | Human` (but not vice versa). See the answer to the linked question for more information. – jcalz Oct 02 '22 at 23:34

1 Answers1

0

That's because of structural typing.

Your object {name:"1", firstName:"2"} does conform the union of your 2 interface.

The behaviour you are observing is called excess property check.

Matthieu Riegler
  • 31,918
  • 20
  • 95
  • 134
  • I looked at your link but this answer is not clear to me. What is the union of your 2 interface? Isn't it *either* one or another interface? Can you add explanation? (Also please have a look at the updated bonus question). –  Oct 02 '22 at 20:17
  • @john That's [excess property check](https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks) ! – Matthieu Riegler Oct 02 '22 at 20:23