user1
user1

Reputation: 586

Compiler error on properties of a variable from interface

I don't understand why the compiler says, in function test1, that property "name" and "surname" don't exist on type "ITest1; I'm confusing...:

interface ITest1{
    name: string;
    surname: string;
    age: number;
}

interface ITest2{
    city: string;
    nation: string;
    isEU: boolean;
}


//function test1<ITest1, ITest2>(a:ITest1|ITest2): ITest1|ITest2{
    function test1<ITest1, ITest2>(a:ITest1|ITest2): string{
   return (a as ITest1).name +
   (a as ITest1).surname;

}

let a : ITest1 = {
    name:"",
    surname:"",
    age:0
};
a.name="John";
a.surname="Taylor";
a.age=30;

console.log(test1(a));

Upvotes: 1

Views: 42

Answers (1)

pzaenger
pzaenger

Reputation: 11993

You need to fix your function (though I am not sure what you want to achieve with <ITest1, ITest2>). Just change it to:

function test1(a: ITest1 | ITest2): string {
  return (a as ITest1).name + (a as ITest1).surname;
}

Output:

$ tsc index.ts && node index
$ JohnTaylor

Edit:

Test for a certain property to differ ITest1 and ITest2:

function test1(a: ITest1 | ITest2 ): string {
  if ('name' in a) {
    // a implements ITest1
    return `${a.name} ${a.surname}`;
  }
  // a implements ITest2
  return `${a.city} ${a.nation}`;

  // Or just:
  // return 'name' in a ? `${a.name} ${a.surname}` : `${a.city} ${a.nation}`;
}

...

console.log(test1(a));
console.log(test1({city: "Foo", nation: "Bar", isEU: false}));

Result:

John Taylor
Foo Bar

Upvotes: 1

Related Questions