打字稿可以使用类接口

时间:2016-09-02 17:40:52

标签: typescript

我有这段代码:

interface Heroe {
    title:string,
    hero:string,
    ranking:number,
}

export class AppComponent {
  heroe : Heroe = {
     title : 'Tour of Heroes',
     hero : 'Windstorm',
     ranking :1
  }
}

如果我替换类而不是接口代码工作:

class Heroe {
    title:string,
    hero:string,
    ranking:number,
}

export class AppComponent {
  heroe : Heroe = {
     title : 'Tour of Heroes',
     hero : 'Windstorm',
     ranking :1
  }
}

使用类接口是正确的,当类没有方法,只有变量类型时,这不是问题吗?在角度演示中使用这种方式,有一个类而不是接口:

https://angular.io/docs/ts/latest/tutorial/toh-pt1.html

在最后一种情况下,我有一个类而不是接口,并没有该类的接口,

正确的不会有接口首先,然后一个类基于接口? ,但如果两者名称相同;怎么打字必须使用?

示例:

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

我也可以将Heroe与界面相同的名字一样吗?

1 个答案:

答案 0 :(得分:2)

“使用类接口这是正确的” 嗯,这取决于你想要做什么,但它不一样:

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 }

编译成:

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

code in playground

正如您所看到的,o1o2明显不同,一个是Heroe类的实例,第二个只是一个与实例具有相同属性的对象。 / p>

在控制台中很清楚:

console.log(o1); // Heroe {title: "title", hero: "hero", ranking: 0}
console.log(o2); // Object {title: "title", hero: "hero", ranking: 0}

即使声明为o2 is because,编译器也不关心Heroe只是一个对象的原因:

  

TypeScript的核心原则之一是类型检查的重点   价值观的形状。这有时被称为“鸭子打字”或   “结构子类型”。

more about Duck typing

或者举例:

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

传递o2很好,因为即使它不是Heroe的实例,它也确实满足了该类的接口。

您可以为接口和类使用相同的名称,但不能重新声明属性,因此这不可行:

interface Heroe {
    title: string; // Error: Duplicate identifier 'title'
}

class Heroe {
    title: string; // Error: Duplicate identifier 'title'
}

但这是:

界面Heroe {     标题:字符串; }

类Heroe {     副标题:字符串; }

声明的顺序无关紧要,你可以在课堂下面设置界面 您可以在Declaration Merging中了解详情。

但您也可以实现一个界面:

interface IHeroe {
    title: string;
    hero: string;
    ranking: number;
}

class Heroe implements IHeroe {
    title: string;
    hero: string;
    ranking: number;
}