TypeScript 中的 interface 和 type 到底有什么区别?

新手上路,请多包涵

type 和 interface 都可以定义对象,二者到底有何区别?

interface Person {
    age: number
    name: string
}

type Person = {
    age: number
    name: string
};
阅读 410
avatarAI BotBETA

在 TypeScript 中,interfacetype 都可以用来定义对象的形状(shape),但它们之间确实有一些关键的区别。

  1. 声明合并(Merging Declarations)
* `interface` 可以被声明合并,这意味着你可以在不同的地方声明同一个 `interface`,并且这些声明会被合并成一个。
* `type` 则不能声明合并。
  1. 继承(Inheritance)
* `interface` 支持继承,这意味着一个 `interface` 可以继承另一个 `interface` 的成员。
* `type` 不支持继承。
  1. 类型别名(Type Aliases)
* `type` 可以是任何有效的 TypeScript 类型,包括基本类型、联合类型、交叉类型、元组等。这使得 `type` 更加灵活,可以用来创建复杂的类型结构。
* `interface` 不能用作类型别名。
  1. 初始化
* `type` 可以被初始化为一个具体的值或对象,而 `interface` 不能。
  1. 函数类型
* 使用 `type` 可以更清晰地表示函数类型,特别是当函数参数或返回值是复杂类型时。
* `interface` 在表示函数类型方面相对较弱。

对于你给出的例子,Person 接口和 Person 类型定义在功能上是等价的,它们都定义了一个对象,该对象具有 age(数字类型)和 name(字符串类型)两个属性。但是,如果你需要更复杂的类型定义或需要利用上述 typeinterface 之间的区别,那么你可能会选择其中之一。

总的来说,选择使用 interface 还是 type 取决于你的具体需求和偏好。在 TypeScript 的早期版本中,interface 是主要的类型定义方式,但随着 type 的引入和功能的增强,type 也变得越来越流行。

3 个回答
✓ 已被采纳

1. type 可以声明基本类型,而 interface 不行

  • type 可以声明基本类型
type Count = number;
type Color = "Red" | "Blue";
  • interface 只能用来声明复杂类型(对象和函数)

2. 扩展时表现不同

  • 扩展 interface 时,TS 将检查扩展的接口是否可以赋值给被扩展的接口。
interface A {
  good(x: number): string;
  bad(x: number): string;
}
interface B extends A {
  good(x: string | number): string;
  bad(x: number): number; // Interface 'B' incorrectly extends interface 'A'.
  // Types of property 'bad' are incompatible.
  // Type '(x: number) => number' is not assignable to type '(x: number) => string'.
  // Type 'number' is not assignable to type 'string'.
}
  • 但使用交叉类型时则不会出现这种情况。我们将上述代码中的接口改写成类型别名,把 extends 换成交集运算符 &,TS 将尽其所能把扩展和被扩展的类型组合在一起,而不会抛出编译时错误。
type A = {
  good(x: number): string;
  bad(x: number): string;
};
type B = A & {
  good(x: string | number): string;
  bad(x: number): number;
};
// ok

3. 多次定义时表现不同

interface 多次的声明会合并。type 不能重复声明。

  • interface 可以定义多次,多次的声明会合并。
interface Point {
  x: number;
}
interface Point {
  y: number;
}
const point: Point = { x: 1 }; //error Property 'y' is missing in type '{ x: number; }' but required in type 'Point'.

const point: Point = { x: 1, y: 1 }; // ok
  • 但是 type 如果定义多次,会报错。
type Point = {
  x: number; //error Duplicate identifier 'A'.
};

type Point = {
  y: number; //error Duplicate identifier 'A'.
};
新手上路,请多包涵

以下是AI的回答

  1. interface

    • 就像你设计蓝图一样,你可以使用interface描述对象应该有的形状和结构。
    • 如果你想让一个类拥有特定的形状,就可以使用interface,这样类就会遵循这个形状。
    • 你可以扩展一个接口,就像添加一些额外的规则一样。
    • 它像是定义了一份合同,告诉别人你期望的对象样子。
    • 当你需要合并多个相同名称的接口时,接口会自动合并。
    interface Person {
        name: string;
        age: number;
    }
    
    const person: Person = {
        name: "Alice",
        age: 30
    };
  2. type

    • type则更像是取了个别名。
    • 你可以用它来表示各种类型,比如基本类型、联合类型、交叉类型等。
    • 它还支持泛型,你可以更灵活地定义类型。
    • 你可以对已有类型进行扩展,就像给它添加了一些额外的特性。
    • 但是它不能被类实现,也不能被扩展。
    type Point = {
        x: number;
        y: number;
    };
    
    const point: Point = {
        x: 10,
        y: 20
    };
  • 如果你需要描述对象的形状,并且想让类来实现这个形状,那么你应该选择interface
  • 而如果你只是想给某个类型取个别名,或者定义一些复杂的类型关系,那么你应该选择type
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Microsoft
子站问答
访问
宣传栏