Reputation: 7054
I have this code:
interface Heroe {
title:string,
hero:string,
ranking:number,
}
export class AppComponent {
heroe : Heroe = {
title : 'Tour of Heroes',
hero : 'Windstorm',
ranking :1
}
}
if I replace Class instead Interface code works:
class Heroe {
title:string,
hero:string,
ranking:number,
}
export class AppComponent {
heroe : Heroe = {
title : 'Tour of Heroes',
hero : 'Windstorm',
ranking :1
}
}
It's correct to use class like interfaces, when class have no methods, just type of variables, that is not a problem?. In angular demo use this way, have a class and not interface:
https://angular.io/docs/ts/latest/tutorial/toh-pt1.html
in this last case I have a class instead Interface, and have no interface for the class,
the correct would not be have Interface first, then a Class based in the interface ? , but if both have the same name; how typescript which must use ??
Example:
interface Heroe {
title:string,
hero:string,
ranking:number,
}
class Heroe interface Heroe {
title:string,
hero:string,
ranking:number,
}
export class AppComponent {
heroe : Heroe = {
title : 'Tour of Heroes',
hero : 'Windstorm',
ranking :1
}
}
I's ok too have Heroe same name class like interface?
Upvotes: 0
Views: 123
Reputation: 164139
"It's correct to use class like interfaces"
Well, that depends on what you're trying to do, but it's not the same:
class Heroe {
title: string;
hero: string;
ranking: number;
constructor(title: string, hero: string, ranking: number) {
this.title = title;
this.hero = hero;
this.ranking = ranking;
}
}
let o1 = new Heroe("title", "hero", 0);
let o2: Heroe = { title: "title", hero: "hero", ranking: 0 }
compiles into:
var Heroe = (function () {
function Heroe(title, hero, ranking) {
this.title = title;
this.hero = hero;
this.ranking = ranking;
}
return Heroe;
}());
var o1 = new Heroe("title", "hero", 0);
var o2 = { title: "title", hero: "hero", ranking: 0 };
As you can see o1
and o2
are clearly different, one is an instance of the Heroe
class and the second is just an object with the same properties as the instance.
It's clear in the console:
console.log(o1); // Heroe {title: "title", hero: "hero", ranking: 0}
console.log(o2); // Object {title: "title", hero: "hero", ranking: 0}
The reason that the compiler doesn't care that o2
is just an object even when declared as Heroe
is because:
One of TypeScript’s core principles is that type-checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”.
Or with an example:
function log(heroe: Heroe) {
console.log(`Title: ${ heroe.title }, Hero: ${ heroe.hero }, Ranking: ${ heroe.ranking }`);
}
log(o1); // obviously this is ok
log(o2); // but this is ok as well
Passing o2
is fine because even if it's not an instance of Heroe
it does satisfy the interface for the class.
You can use the same name for an interface and a class, but you can't redeclare properties, so this is not ok:
interface Heroe {
title: string; // Error: Duplicate identifier 'title'
}
class Heroe {
title: string; // Error: Duplicate identifier 'title'
}
But this is:
interface Heroe { title: string; }
class Heroe { subtitle: string; }
The order of the declarations doesn't matter, you can have the interface below the class.
You can read more about this in Declaration Merging.
But you can also implement an interface:
interface IHeroe {
title: string;
hero: string;
ranking: number;
}
class Heroe implements IHeroe {
title: string;
hero: string;
ranking: number;
}
Upvotes: 2