最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解TypeScript中type與interface的區(qū)別

 更新時(shí)間:2022年04月07日 15:06:12   作者:芝士  
在寫 ts 相關(guān)代碼的過程中,總能看到 interface 和 type 的身影。它們的作用好像都一樣的,相同的功能用哪一個(gè)都可以實(shí)現(xiàn),也都很好用,所以也很少去真正的理解它們之間到底有啥區(qū)別,因此本文將詳細(xì)講解二者的區(qū)別,需要的可以參考一下

類型別名 type

首先認(rèn)識(shí)一下什么是類型別名?

類型別名用來給一個(gè)類型起個(gè)新名字,使用 type 創(chuàng)建類型別名,類型別名不僅可以用來表示基本類型,還可以用來表示對(duì)象類型、聯(lián)合類型、元組和交集。讓我們看一些例子:

type userName = string; // 基本類型
type userId = string | number; // 聯(lián)合類型
type arr = number[];  
// 對(duì)象類型
type Person = {
    id: userId; // 可以使用定義類型
    name: userName;
    age: number;
    gender: string;
    isWebDev: boolean;
};
// 范型
type Tree<T> = { value: T };
const user: Person = {
    id: "901",
    name: "椿",
    age: 22,
    gender: "女",
    isWebDev: false,
};
const numbers: arr = [1, 8, 9];

接口 interface

接口是命名數(shù)據(jù)結(jié)構(gòu)(例如對(duì)象)的另一種方式;與type 不同,interface僅限于描述對(duì)象類型。

接口的聲明語(yǔ)法也不同于類型別名的聲明語(yǔ)法。讓我們將上面的類型別名 Person 重寫為接口聲明:

interface Person {
    id: userId;
    name: userName;
    age: number;
    gender: string;
    isWebDev: boolean;
}

interface和type的相似之處

在討論二者區(qū)別之前, 首先看一下二者的相似之處(為何開發(fā)中,我們覺得用哪個(gè)都一樣)

都可以描述 Object和Function

兩者都可以用來描述對(duì)象或函數(shù),但語(yǔ)法不同:

Type

type Point = {
  x: number;
  y: number;
};
type SetPoint = (x: number, y: number) => void;

Interface

interface Point {
  x: number;
  y: number;
}
interface SetPoint {
  (x: number, y: number): void;
}

二者都可以被繼承

interface 和 type 都可以繼承。

另一個(gè)值得注意的是,接口和類型別名并不互斥。類型別名可以繼承接口,反之亦然。只是在實(shí)現(xiàn)形式上,稍微有些差別。

interface 繼承 interface

interface Person{
    name:string
}
interface Student extends Person { stuNo: number }

interface 繼承 type

type Person{
    name:string
}
interface Student extends Person { stuNo: number }

type 繼承 type

type Person{
    name:string
}
type Student = Person & { stuNo: number }

type 繼承 interface

interface Person{
    name:string
}
type Student = Person & { stuNo: number }

實(shí)現(xiàn) implements

類可以實(shí)現(xiàn)interface 以及 type(除聯(lián)合類型外)

interface ICat{
    setName(name:string): void;
}
class Cat implements ICat{
    setName(name:string):void{
        // todo
    }
}
// type  
type ICat = {
    setName(name:string): void;
}
class Cat implements ICat{
    setName(name:string):void{
        // todo
    }
}

上面提到了特殊情況,類無法實(shí)現(xiàn)聯(lián)合類型, 是什么意思呢?

type Person = { name: string; } | { setName(name:string): void };
// 無法對(duì)聯(lián)合類型Person進(jìn)行實(shí)現(xiàn)
// error: A class can only implement an object type or intersection of object types with statically known members.
class Student implements Person {
  name= "張三";
  setName(name:string):void{
        // todo
    }
}

上面聊了interface與 type的相似之處, 接下來就來看看他們的區(qū)別。

二者區(qū)別

1. 定義基本類型別名

type可以定義基本類型別名, 但是interface無法定義,如:

type userName = string
type stuNo = number
...

2. 聲明聯(lián)合類型

type可以聲明聯(lián)合類型, 例如:

type Student = {stuNo: number} | {classId: number}

3. 聲明元組

type可以聲明 元組類型:

type Data = [number, string];

以上都是 type能做到, 而interface做不到的, 接下來聊聊type做不到的

4. 聲明合并

如果你多次聲明一個(gè)同名的接口,TypeScript 會(huì)將它們合并到一個(gè)聲明中,并將它們視為一個(gè)接口。這稱為聲明合并, 例如:

interface Person { name: string }
interface Person { age: number }
let user: Person = {
    name: "Tolu",
    age: 0,
};

這種情況下,如果是type的話,重復(fù)使用Person是會(huì)報(bào)錯(cuò)的:

type Person { name: string };  
// Error: 標(biāo)識(shí)符“Person”重復(fù)。ts(2300)
type Person { age: number }

5. 索引簽名問題

如果你經(jīng)常使用TypeScript, 一定遇到過相似的錯(cuò)誤:

Type 'xxx' is not assignable to type 'yyy'

Index signature is missing in type 'xxx'.

看個(gè)例子來理解問題:

interface propType{
    [key: string] : string
}
let props: propType
type dataType = {
    title: string
}
interface dataType1 {
    title: string
}
const data: dataType = {title: "訂單頁(yè)面"}
const data1: dataType1 = {title: "訂單頁(yè)面"}
props = data
// Error:類型“dataType1”不可分配給類型“propType”; 類型“dataType1”中缺少索引簽名  
props = data1

我們發(fā)現(xiàn)dataType和dataType1對(duì)應(yīng)的類型一樣,但是interface定義的就賦值失敗,是什么原因呢?剛開始百思不解,最后我在 stack overflow上找到了一個(gè)相似的問題:

并且很幸運(yùn)的找到了有效的答案:

翻譯過來的大致意思就是:

Record<string,string>與{[key:string]:string}相同。只有當(dāng)該類型的所有屬性都已知并且可以對(duì)照該索引簽名進(jìn)行檢查時(shí),才允許將子集分配給該索引簽名類型。在您的例子中,從exampleType到Record<string,string>的所有內(nèi)容都是可分配的。這只能針對(duì)對(duì)象字面量類型進(jìn)行檢查,因?yàn)橐坏┞暶髁藢?duì)象字面量類型,就無法更改它們。因此,索引簽名是已知的。

相反,在你使用interface去聲明變量時(shí),它們?cè)谀且豢填愋筒⒉皇亲罱K的類型。由于interfac可以進(jìn)行聲明合并,所以總有可能將新成員添加到同一個(gè)interface定義的類型上。

再結(jié)合:point_up_2:第4點(diǎn) 聲明合并的講解, 這樣就很好理解了。就是說interface定義的類型是不確定的, 后面再來一個(gè):

interface propType{
    title:number
}

這樣propType類型就被改變了。

總結(jié)

官方推薦用 interface,其他無法滿足需求的情況下用 type。

但其實(shí),因?yàn)?聯(lián)合類型 和 交叉類型 是很常用的,所以避免不了大量使用 type 的場(chǎng)景,一些復(fù)雜類型也需要通過組裝后形成類型別名來使用。

所以,如果想保持代碼統(tǒng)一,還是可選擇使用 type。通過上面的對(duì)比,類型別名 其實(shí)可涵蓋 interface 的大部分場(chǎng)景。

對(duì)于 React 組件中 props及 state,使用 type ,這樣能夠保證使用組件的地方不能隨意在上面添加屬性。如果有自定義需求,可通過 HOC二次封裝。

編寫三方庫(kù)時(shí)使用interface,其更加靈活自動(dòng)的類型合并可應(yīng)對(duì)未知的復(fù)雜使用場(chǎng)景。

以上就是詳解TypeScript中type與interface的區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于TypeScript type interface區(qū)別的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳談javascript異步編程

    詳談javascript異步編程

    這篇文章主要為大家詳細(xì)介紹了javascript異步編程,其實(shí)作為一種編程語(yǔ)言Javascript的異步編程是一個(gè)非常值得討論的有趣話題,感興趣的小伙伴們可以參考一下
    2016-02-02
  • js使用child_process模塊操作cmd命令

    js使用child_process模塊操作cmd命令

    這篇文章主要給大家介紹了關(guān)于js使用child_process模塊操作cmd命令的相關(guān)資料,在JavaScript中執(zhí)行CMD命令非常靈活,可以執(zhí)行任何CMD命令,例如:復(fù)制、移動(dòng)、刪除文件等等,需要的朋友可以參考下
    2024-01-01
  • JavaScript單線程和任務(wù)隊(duì)列原理解析

    JavaScript單線程和任務(wù)隊(duì)列原理解析

    這篇文章主要介紹了JavaScript單線程和任務(wù)隊(duì)列原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 小程序云開發(fā)部署攻略(圖文教程)

    小程序云開發(fā)部署攻略(圖文教程)

    微信小程序的云開發(fā)功能剛剛上線,這篇文章主要介紹了小程序云開發(fā)部署攻略(圖文教程),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-10-10
  • 如何用JS追蹤用戶

    如何用JS追蹤用戶

    本文介紹如何編寫JavaScript腳本,將用戶數(shù)據(jù)發(fā)回服務(wù)器。對(duì)此感興趣的同學(xué),可以參考下
    2021-05-05
  • Bootstrap輸入框組件簡(jiǎn)單實(shí)現(xiàn)代碼

    Bootstrap輸入框組件簡(jiǎn)單實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了Bootstrap輸入框組件的簡(jiǎn)單實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 這樣回答繼承可能面試官更滿意

    這樣回答繼承可能面試官更滿意

    這篇文章主要介紹了這樣回答繼承可能面試官更滿意,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-12-12
  • JavaScript 垃圾回收機(jī)制分析

    JavaScript 垃圾回收機(jī)制分析

    同C# 、Java一樣我們可以手工調(diào)用垃圾回收程序,但是由于其消耗大量資源,而且我們手工調(diào)用的不會(huì)比瀏覽器判斷的準(zhǔn)確,所以不推薦手工調(diào)用垃圾回收
    2013-10-10
  • javascript使用activex控件的代碼

    javascript使用activex控件的代碼

    最近公司項(xiàng)目用到了avtivex控件。以前從來沒有用過。我把最近到處找到的使用方法整理一下。
    2011-01-01
  • 使用js Math.random()函數(shù)生成n到m間的隨機(jī)數(shù)字

    使用js Math.random()函數(shù)生成n到m間的隨機(jī)數(shù)字

    何使用js生成n到m間的隨機(jī)數(shù)字,主要目的是為后期的js生成驗(yàn)證碼做準(zhǔn)備,Math.random()函數(shù)返回0和1之間的偽隨機(jī)數(shù)
    2014-10-10

最新評(píng)論

买车| 历史| 勐海县| 邹平县| 通山县| 凤阳县| 台中县| 宜州市| 大丰市| 黑水县| 嘉兴市| 马龙县| 通化县| 宣汉县| 迭部县| 调兵山市| 图木舒克市| 天津市| 桃源县| 德化县| 房产| 湘潭市| 开封市| 大冶市| 丰城市| 任丘市| 渭南市| 大荔县| 南雄市| 新干县| 方正县| 小金县| 长丰县| 宜黄县| 景泰县| 新闻| 台中县| 峨眉山市| 左贡县| 扎兰屯市| 易门县|