ts 中的 type 和 interface 有什么区别?

一、用法举例

ts 复制代码
interface Person {
    name: string
    age: number
}

const person: Person = {
    name: 'Kite',
    age: 24
}
ts 复制代码
type Person = {
    name: string
    age: number
}

const person: Person = {
    name: 'Kite',
    age: 24
}

二、翻阅 ts 的官方文档

1、interface 接口

TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做"鸭式辨型法"或"结构性子类型化"。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

ts 复制代码
interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
2、type 类型别名

类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值联合类型元组以及其它任何你需要手写的类型。

类型别名只是给类型起一个新名字。它并不是一个类型,只是一个别名而已, 就像通常我们 在 alias 下给 src 目录配置 @ 别名。

ts 复制代码
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    }
    else {
        return n();
    }
}
// 调用getName 时传字符串和函数都可以,如果传的格式有问题,就会提示
getName('Kite')
getName(() => 'Kite')

interface 叫 接口 和 type 叫类型别名,只是有时候两者都能实现同样的功能,才会经常被混淆。

三、两者相同点

1、都可以定义一个对象或函数

定义对象前面已经说了,我们来看一下如何定义函数。

ts 复制代码
type addType = (num1:number,num2:number) => number

interface addType {
    (num1:number,num2:number):number
}

这两种写法都可以定义函数类型

ts 复制代码
const add:addType = (num1, num2) => {
    return num1 + num2
}

2、都允许继承(extends)

我们定义一个 Person 类型和 Student 类型,Student 继承自 Person,可以有下面四种方式

  • interface 继承 interface
ts 复制代码
interface Person { 
  name: string 
}
interface Student extends Person { 
  grade: number 
}

const person:Student = {
  name: 'lin',
  grade: 100
}
  • type 继承 type
ts 复制代码
type Person = { 
  name: string 
}
type Student = Person & { grade: number  }    // 用交叉类型
  • interface 继承 type
ts 复制代码
type Person = { 
  name: string 
}
interface Student extends Person { 
  grade: number 
}
  • type 继承 interface
ts 复制代码
interface Person { 
  name: string 
}

type Student = Person & { grade: number  }    // 用交叉类型

interface 使用 extends 实现继承, type 使用交叉类型实现继承

四、两者不同点

1、type 可以,interface 不行

类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。
声明基本类型、联合类型、交叉类型、元组

ts 复制代码
type Name = string                              // 基本类型

type arrItem = number | string                  // 联合类型

const arr: arrItem[] = [1,'2', 3]

type Person = { 
  name: Name 
}

type Student = Person & { grade: number  }       // 交叉类型

type Teacher = Person & { major: string  } 

type StudentAndTeacherList = [Student, Teacher]  // 元组类型

const list:StudentAndTeacherList = [
  { name: 'lin', grade: 100 }, 
  { name: 'liu', major: 'Chinese' }
]
2、interface可以,type 不行

合并重复声明

ts 复制代码
interface Person {
    name: string
}

interface Person {         // 重复声明 interface,就合并了
    age: number
}

const person: Person = {
    name: 'lin',
    age: 18
}

重复声明 type ,就报错了

ts 复制代码
type Person = {
    name: string
}

type Person = {     // Duplicate identifier 'Person'
    age: number
}

const person: Person = {
    name: 'lin',
    age: 18
}

五、小结

  • interface 和 type 被 TS 设计出来,是完全不同的东西,有各自的职责。
  • interface 是接口,用于描述一个对象。type 是类型别名,用于给各种类型定义别名,让 TS 写起来更简洁、清晰。
  • 使用场景: 一般使用组合或者交叉类型的时候,用 type ; 一般要用类的 extends 或 implements 时,用 interface。
相关推荐
Restart-AHTCM5 小时前
AI 时代的大前端崛起,TypeScript 重塑前端开发
前端·人工智能·typescript·ai编程·a
一袋米扛几楼985 小时前
【报错问题】解决 Vercel 部署报错:Express 类型失效与 TypeScript 2349/2339/2769 错误排查
ubuntu·typescript·express
一袋米扛几楼988 小时前
【报错问题】彻底解决 TypeScript 报错 TS2769: No overload matches this call (JWT 篇)
linux·javascript·typescript
涵涵(互关)8 小时前
语法大全-only-writer-two
前端·vue.js·typescript
漫游的渔夫9 小时前
前端开发者做 Agent:Tool Calling 别只写函数名,用 Schema 少踩 5 个坑
前端·人工智能·typescript
zhensherlock11 小时前
Protocol Launcher 系列:Beorg 高效任务管理的协议支持
前端·javascript·typescript·node.js·自动化·github·js
深海鱼在掘金21 小时前
深入浅出 LangChain —— 第二章:环境搭建与快速上手
人工智能·typescript·langchain
俺不会敲代码啊啊啊1 天前
el-table实现行拖拽(包含展开项)
前端·vue.js·typescript
懒人村杂货铺1 天前
Express + TypeScript 后端通用标准规范
javascript·typescript·express
涵涵(互关)1 天前
语法大全-only-writer
开发语言·前端·vue.js·typescript