新聞中心
如果你簡歷上的技能有寫 TypeScript,那么面試官可能會(huì)問你 type 和 interface 之間有什么區(qū)別?你知道怎么回答這個(gè)問題么?如果不知道的話,那看完本文也許你就懂了。

創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站建設(shè)、蛟河網(wǎng)絡(luò)推廣、重慶小程序開發(fā)公司、蛟河網(wǎng)絡(luò)營銷、蛟河企業(yè)策劃、蛟河品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供蛟河建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
類型別名 type 可以用來給一個(gè)類型起個(gè)新名字,當(dāng)命名基本類型或聯(lián)合類型等非對象類型時(shí)非常有用:
type MyNumber = number;
type StringOrNumber = string | number;
type Text = string | string[];
type Point = [number, number];
type Callback = (data: string) => void;
在 TypeScript 1.6 版本,類型別名開始支持泛型。我們工作中常用的 Partial、Required、Pick、Record 和 Exclude 等工具類型都是以 type 方式來定義的。
// lib.es5.d.ts
type Partial= {
[P in keyof T]?: T[P];
};
type Required= {
[P in keyof T]-?: T[P];
};
type Pick= {
[P in K]: T[P];
};
type Record= {
[P in K]: T;
};
type Exclude= T extends U ? never : T;
而接口 interface 只能用于定義對象類型,Vue 3 中的 App 對象就是使用 interface 來定義的:
// packages/runtime-core/src/apiCreateApp.ts
export interface App{
version: string
config: AppConfig
use(plugin: Plugin, ...options: any[]): this
mixin(mixin: ComponentOptions): this
component(name: string): Component | undefined // Getter
component(name: string, component: Component): this // Setter
directive(name: string): Directive | undefined
directive(name: string, directive: Directive): this
}
由以上代碼可知,在定義接口時(shí),我們可以同時(shí)聲明對象類型上的屬性和方法。了解 type 和 interface 的作用之后,我們先來介紹一下它們的相似之處。
1、類型別名和接口都可以用來描述對象或函數(shù)。
類型別名
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
在以上代碼中,我們通過 type 關(guān)鍵字為對象字面量類型和函數(shù)類型分別取了一個(gè)別名,從而方便在其他地方使用這些類型。
接口
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}2、類型別名和接口都支持?jǐn)U展。
類型別名通過 &(交叉運(yùn)算符)來擴(kuò)展,而接口通過 extends 的方式來擴(kuò)展。
類型別名擴(kuò)展
type Animal = {
name: string
}
type Bear = Animal & {
honey: boolean
}
const bear: Bear = getBear()
bear.name
bear.honey
接口擴(kuò)展
interface Animal {
name: string
}
interface Bear extends Animal {
honey: boolean
}
此外,接口也可以通過 extends 來擴(kuò)展類型別名定義的類型:
type Animal = {
name: string
}
interface Bear extends Animal {
honey: boolean
}
同樣,類型別名也可以通過 &(交叉運(yùn)算符)來擴(kuò)展已定義的接口類型:
interface Animal {
name: string
}
type Bear = Animal & {
honey: boolean
}
了解完 type 和 interface 的相似之處之后,接下來我們來介紹它們之間的區(qū)別。
1、類型別名可以為基本類型、聯(lián)合類型或元組類型定義別名,而接口不行。
type MyNumber = number;
type StringOrNumber = string | number;
type Point = [number, number];
2、同名接口會(huì)自動(dòng)合并,而類型別名不會(huì)。
同名接口合并
interface User {
name: string;
}
interface User {
id: number;
}
let user: User = { id: 666, name: "阿寶哥" };
user.id; // 666
user.name; // "阿寶哥"
同名類型別名會(huì)沖突
type User = {
name: string;
};
// 標(biāo)識符“User”重復(fù)。ts(2300)
type User = { //Error
id: number;
};
利用同名接口自動(dòng)合并的特性,在開發(fā)第三方庫的時(shí)候,我們就可以為使用者提供更好的安全保障。比如 webext-bridge 這個(gè)庫,使用 interface 定義了 ProtocolMap 接口,從而讓使用者可自由地?cái)U(kuò)展 ProtocolMap 接口。
之后,在利用該庫內(nèi)部提供的 onMessage 函數(shù)監(jiān)聽自定義消息時(shí),我們就可以推斷出不同消息對應(yīng)的消息體類型。
擴(kuò)展 ProtocolMap 接口
import { ProtocolWithReturn } from 'webext-bridge'
declare module 'webext-bridge' {
export interface ProtocolMap {
foo: { title: string }
bar: ProtocolWithReturn
}
}
監(jiān)聽自定義消息
import { onMessage } from 'webext-bridge'
onMessage('foo', ({ data }) => {
// type of `data` will be `{ title: string }`
console.log(data.title)
}
使用類型別名的場景:
- 定義基本類型的別名時(shí),使用 type。
- 定義元組類型時(shí),使用 type。
- 定義函數(shù)類型時(shí),使用 type。
- 定義聯(lián)合類型時(shí),使用 type。
- 定義映射類型時(shí),使用 type。
使用接口的場景:
- 需要利用接口自動(dòng)合并特性的時(shí)候,使用 interface。
- 定義對象類型且無需使用 type 的時(shí)候,使用 interface。
文章題目:Type和Interface傻傻分不清楚?
當(dāng)前地址:http://www.dlmjj.cn/article/codssoe.html


咨詢
建站咨詢
