在Typescript中,类型和接口有什么区别?


114

以下内容有什么区别?

type Foo = { 
    foo: string 
};
interface Foo {
   foo: string;
}

3
类型不能像接口扩展那样扩展。类型只是类型的别名。
PSL


2
我通常将类型用于外部数据,例如来自JSON文件的类型,或者如果您仅在不使用OOP类的情况下编写函数。
Kokodoko

1
我发现这篇文章有用,解释差异- medium.com/@martin_hotell/...
桑迪普GB

1
接受的答案已过期。更新的解释发布在这里(因为该线程似乎受到Google的青睐):stackoverflow.com/questions/37233735/…–
jabacchetta

Answers:


125

接口可以扩展

interface A {
  x: number;
}
interface B extends A {
  y: string;
}

并且也增加了

interface C {
  m: boolean;
}
// ... later ...
interface C {
  n: number;
}

但是,类型别名可以表示接口不能执行的某些操作

type NumOrStr = number | string;
type NeatAndCool = Neat & Cool;
type JustSomeOtherName = SomeType;

因此,通常,如果您只有一个简单的对象类型(如您的问题所示),则接口通常是一种更好的方法。如果您发现自己想写一些不能写为接口的东西,或者只是想给另一个名字,那么类型别名会更好。


3
Type aliases, however, can represent some things interfaces can't在我看来,你的例子NeatAndCoolJustSomeOtherName可以作为接口,扩展现有的创建NeatCoolSomeType类型。
Rudey

实际上,可以使用以下接口创建第二个和第三个示例:interface NeatAndCool extends Neat, Cool {} interface JustSomeOtherName extends SomeType {}
peterjwest

3
扩展两个接口并不总是会产生与交集类型相同的结果,并且并非所有类型都可以扩展(而所有类型都可以使用别名或放入并集/交集)
Ryan Cavanaugh

1
那么类型的优势是什么?我们可以说当我们有接口时,类型没有用吗?
Mostafa Saadatnia


4

类型有点像接口,反之亦然:两者都可以由类实现。但是有一些重要的区别:1.当用类实现Type时,必须在类内部初始化属于Type的属性,而必须使用Interface声明它们。2.如@ryan所述:接口可以扩展另一个接口。类型不能。

type Person = {
    name:string;
    age:number;
}

// must initialize all props - unlike interface
class Manager implements Person {
    name: string = 'John';
    age: number = 55;

    // can add props and methods
    size:string = 'm';
}

const jane : Person = {
    name :'Jane',
    age:46,

    // cannot add more proprs or methods
    //size:'s'
}

4

这些线程之间也已经存在差异。

type Foo = {
    foo: string
};
interface Foo {
    foo: string;
}

在这里type Foointerface Foo外观几乎相似,因此令人困惑。

interface是一个约定,foo:string对象中应包含以下属性(在此处)。 interface不是class。语言不支持多重继承时使用。因此interface可以是不同类之间的通用结构。

class Bar implements Foo {
    foo: string;
}

let p: Foo = { foo: 'a string' };

但是typeinterface用于非常不同的上下文。

let foo: Foo;
let today: Date = new Date();

这里typefooFootodayDate。它就像一个变量定义,其中包含其他变量的类型信息。 type就像接口,类,函数签名,其他类型甚至值(如type mood = 'Good' | 'Bad')的超集。最后type描述了变量的可能结构或值。


4

说“可以实现接口”是错误的,因为类型也可以实现

type A = { a: string };


class Test implements A {

    a: string;
}

尽管可以做到这一点,但是您不能实现一个类型为Union的类型,这完全是说得通的:)


4

打字稿中的type用于引用现有的类型。它不能像一样扩展interface。的例子type有:

type Money = number;
type FormElem = React.FormEvent<HTMLFormElement>;
type Person = [string, number, number];

您可以在以下类型中使用“休息”和“传播”:

type Scores = [string, ...number[]];
let ganeshScore = ["Ganesh", 10, 20, 30]
let binodScore = ["Binod", 10, 20, 30, 40]

另一方面,界面允许您创建新类型。

interface Person{
  name: string,
  age: number, 
}

Interface can be extended with extends keyword.
interface Todo{
  text: string;
  complete: boolean;
}

type Tags = [string, string, string]

interface TaggedTodo extends Todo{
 tags: Tags
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.