TypeScript中type和interface的区别及注意事项

作者:闭包旅人

时间:2026-10-26

浏览:162

本文深入解析TypeScript中type与interface的核心差异。type侧重于类型别名与复用,支持非对象类型及交叉类型模拟继承;interface专注于对象结构定义,支持声明合并与真正的接口继承。文章通过代码示例对比两者在扩展、字段添加及编译器提示上的不同表现,并给出对象结构定义优先使用interface的建议。

文章目录

前言

在 TypeScript 中,type 和 interface 在功能上具有相似性,均可用于为类型命名并通过该名称引用对应的类型。然而,两者在底层机制和适用场景上存在显著差异,开发者在实际编码时需留意这些区别以选择合适的方式。

概念

type

type 关键字用于声明类型别名。其基本语法结构如下所示:

type AliasName = Type;
  • type:声明类型别名的关键字
  • AliasName:类型别名的名称
  • Type:类型别名关联的具体类型

interface

通过关键字 interface 可以定义一个接口类型。接口的一个显著特性是能够将多个类型声明合并为一个统一的类型声明。

需要注意的是,接口声明仅存在于编译阶段,编译生成的 JavaScript 代码中不会包含任何接口相关的代码。

其语法格式如下:

interface InterfaceName {
  TypeMember;
  TypeMember;
  ...
}
  • interface:定义接口的关键字
  • InterfaceName:接口名,首字母需要大写
  • TypeMember:接口的类型成员

异同点

不同点

  • type 在声明类型别名后实质上执行的是赋值操作,即将别名与具体类型关联。这意味着类型别名并未创建新的类型,而是对已有类型的引用。相比之下,interface 则是定义了一个全新的接口类型。
  • type 能够表示非对象类型(如基本类型、联合类型等),而 interface 仅能用于表示对象类型。
  • interface 可以继承其他接口或类,但 type 本身不支持直接的继承语法。

部分文章声称 type 也支持继承,这种说法并不严谨。对于类型别名而言,可以通过交叉类型(Intersection Types)来实现类似继承的效果,但该方法仅适用于对象类型的类型别名,对非对象类型无效。

type Shape = { name: string }

type Circle = Shape & { radius: number }

function foo(circle: Circle) {
  const name = circle.name
  const radius = circle.radius
}

interface 的接口名通常会直接显示在编译器的诊断信息和代码编辑器的智能提示中。而 type 的名字仅在特定情况下才会显示——即当类型别名表示数组类型、元组类型以及类或者接口的泛型实例类型时才会展示。

type NumericType = number | bigint;

interface Circle {
  radius: number;
}

function f(value: NumericType, circle: Circle) {
  const bar: boolean = value;
  //    ~~~
  // 	  Type 'number | bigint' is not assignable to type 'boolean'
  // 		这里没有显示类型别名
  
  const baz: boolean = circle;
  // 	  ~~~
  // 		Type 'Circle' is not assignable to type 'boolean'
}
  • interface 具有声明合并(Declaration Merging)的行为,而 type 不具备此特性。这意味着我们可以通过多次声明同名 interface 来扩展其属性。
  • type 可以通过 typeof 操作符获取实例的类型,从而进行赋值操作。

相同点

两者均可用于定义对象或函数的结构。从严格意义上讲,type 更多体现为一种引用关系,而 interface 则侧重于定义行为。

补充:Ts中type和interface定义类型扩展类型的方法

在 TypeScript 中,我们可以通过 type 和 interface 来定义类型。通常情况下,通过 interface 定义的类型也可以用 type 来定义,但需注意 type 定义时必须添加等号,而 interface 定义时不需要。

以下代码展示了使用 type 声明一个 string 类型的示例。

type user=string
//接收一个字符串类型的数据,返回一个user类型(字符串类型)的数据
function Input(str:string):user{
    return str.slice(0,2)
}
//把返回结果赋值给userInput
let userInput=Input('hello')
//重新给其赋值一个字符串类型的值,没有报错,说明用type声明的字符串类型生效
userInput='new'

以下代码展示了使用 interface 声明一个对象类型的示例。

interface Point{
    x:number,
    y:number
}
//接收一个Point的对象类型数据
function printCoord(pt:Point){
 
}
//给函数传一个对象类型的数据,没有报错,说明用interface声明的类型生效
printCoord({
    x:100,
    y:100
})

接口扩展:可以在 interface 后使用 extends 关键字来扩展接口。对于类型别名 type,则需要使用 & 符号来扩展接口。

以下代码展示了使用 extends 扩展接口的示例。

//扩展接口
interface Animal{
    name:string
}
interface Bear extends Animal{
    honey:boolean
}
//声明一个类型为Bear类型的对象,要求既要有name,也要有honey。说明用extends扩展接口成功
const bear:Bear={
    name:'winie',
    honey:true
}
console.log(bear.name);
console.log(bear.honey);

以下代码展示了使用 type 扩展接口的示例。

//扩展类型
type Animal={
    name:string
}
//给Animal扩展接口
type Bear=Animal&{
    honey:boolean
}
const bear:Bear={
    name:'winie',
    honey:true
}

向现有类型添加新字段时,interface 可以通过定义同名接口的方式扩展字段,而类型别名 type 不能通过同名的方式进行扩展。

以下代码展示了 interface 通过定义同名的方式向现有类型添加新字段。

//向现有的类型添加新字段
interface MyWindow{
    title:string
}
interface MyWindow{
    count:number
}
const w:MyWindow={
    title:'wz',
    count:666
}

以下代码会报错,因为类型别名 type 不能通过同名的方式进行扩展。

//类型创建后不能更改
type MyWindow={
    title:string
}
type MyWindow={
 
}

总结

对于 type 而言,其主要用途是对类型进行复用。例如在项目中遇到复杂或冗长的类型定义时,可以使用 type 直接引用该类型:

type FType = boolean | string | number;

而对于 interface 来说,它是专门用于定义接口类型(约束数据类型和属性)的,且接口类型支持继承和声明合并。

因此,在定义对象结构的类型时,建议尽可能使用 interface,并在合适的场景下使用 type。

到此这篇关于TypeScript中type和interface区别及注意事项的文章就介绍到这了,更多相关TS type和interface区别内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章