欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Typescript中 type 與 interface 的區(qū)別說明總結(jié)

 更新時(shí)間:2024年07月14日 07:44:00   作者:傲慢或香橙  
這篇文章主要介紹了Typescript中 type 與 interface 的區(qū)別說明總結(jié),需要的朋友可以參考下

Typescript類型別名 type

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

// 基本類型
type userName = string;
// 聯(lián)合類型
type userId = string | number;
// 數(shù)組類型
type arr = number[];
// 對象類型
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];

Typescript接口 interface

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

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

語法不同

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

擴(kuò)展 (繼承)不同

擴(kuò)展 (繼承) 語法:interface 使用 extends,type 使用 &

// extends方式不同
interface PartialPointX { x: number }
interface Point extends PartialPointX { y: number }

type PartialPointX = { x: number }
// & 交叉類型
type Point = PartialPointX & { y: number }

兩者也可以互相繼承

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

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

同名合并

interface 支持,type 不支持(如果系統(tǒng)中存在兩個(gè)使用 interface 定義的接口且同名的話,系統(tǒng)則會自動(dòng)合并它們),如果存在兩個(gè)同名 type 則會報(bào)錯(cuò)

// interface可以定義多次,并將被視為單個(gè)接口
// These two declarations become:
// interface Point { x: number; y: number }
interface Point { x: number }
interface Point { y: number }

描述類型

對象、函數(shù)兩者都適用,但是 type 可以用于基礎(chǔ)類型描述、聯(lián)合類型、元組(簡單類型用 type 來定義)

type test = number //基本類型
let num: test = 10
type userOjb = { name:string } // 對象
type getName = () => string  // 函數(shù)
type data = [number, string] // 元組
type numOrFun = userOjb | getName  // 聯(lián)合類型

interface Common {
  name: string
}
interface Person<T> extends Common {
  age: T
  sex: string
}
type People<T> = {
  age: T
  sex: string
} & Common
// 聯(lián)合類型
type P1 = Person<number> | People<number>
// 元組
type P2 = [Person<number>, People<number>]

映射類型

type 支持計(jì)算屬性,生成映射類型,interface 不支持

場景: 有時(shí)候一個(gè)類型需要基于另外一個(gè)類型,但是你又不想拷貝一份,這個(gè)時(shí)候你可以考慮使用映射類型

// keys 聯(lián)合類型
type Keys = 'firstName' | 'surName'

// DudeType 會遍歷 keys 所有屬性,然后設(shè)置為 string 類型
type DudeType = {
    [key in Keys]: string
}

const test: DudeType = {
    firstName:'Paerl'
    surName:'Grz'
}

// 報(bào)錯(cuò)
//interface DudeType2 {
//  [key in keys]: string
//}


// 帶泛型的映射類型
// 在這個(gè)例子中,OptionsFlags 會遍歷 Type 所有的屬性,然后設(shè)置為布爾類型
type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean
};

type FeatureFlags = {
  darkMode: () => void
  newUserProfile: () => void
};

type FeatureOptions = OptionsFlags<FeatureFlags>
// type FeatureOptions = {
//    darkMode: boolean
//    newUserProfile: boolean
// }

interface 可以被 class 實(shí)現(xiàn)

interface 和 type 都可以實(shí)現(xiàn)一個(gè)函數(shù)的類型,但是 interface 可以被 類class 實(shí)現(xiàn)(implements),type 不行

interface SetPerson {
  (age: number, sex: string): void
}

type SetPeople = (age: number, sex: string) => void


let setPerson: SetPerson = function (age, sex) {}
let setPeople: SetPeople = function (age, sex) {}


class Config implements SetPerson {
  setPerson(age: number, sex: string) {
    // do nothing
  }
}

type 可以配合 typeof

type 可以結(jié)合 typeof 使用,interface 不行

class Config {
  setPerson(age: number, sex: string) {
    // do nothing
  }
}
// 獲取 Config class 的類型
type T = typeof Config

const C: T = class {
  setPerson(age: number, sex: string) {
    // do nothing
  }
}

總結(jié)

雖然 官方 中說幾乎接口的所有特性都可以通過類型別名來實(shí)現(xiàn),但建議優(yōu)先選擇接口,接口滿足不了再使用類型別名,在 typescript 官網(wǎng) Preferring Interfaces Over Intersections 有說明,具體內(nèi)容如下:

大多數(shù)時(shí)候,對象類型的 簡單 類型別名 的作用與 接口 非常相似

interface Foo { prop: string }

type Bar = { prop: string };

但是,一旦你需要組合兩個(gè)或多個(gè)類型來實(shí)現(xiàn)其他類型時(shí),你就可以選擇使用接口擴(kuò)展這些類型,或者使用類型別名將它們交叉在一個(gè)中(交叉類型),這就是差異開始的時(shí)候。

接口創(chuàng)建一個(gè)單一的平面對象類型來檢測屬性沖突,這通常很重要! 而交叉類型只是遞歸的進(jìn)行屬性合并,在某種情況下可能產(chǎn)生 never 類型

接口也始終顯示得更好,而交叉類型做為其他交叉類型的一部分時(shí),直觀上表現(xiàn)不出來,還是會認(rèn)為是不同基本類型的組合。

接口之間的類型關(guān)系會被緩存,而交叉類型會被看成組合起來的一個(gè)整體。

最后一個(gè)值得注意的區(qū)別是,在檢查到目標(biāo)類型之前會先檢查每一個(gè)組分。

出于這個(gè)原因,建議使用 接口/擴(kuò)展interface/extends 擴(kuò)展類型而不是創(chuàng)建 交叉類型&。

- type Foo = Bar & Baz & {
-     someProp: string;
- }


+ interface Foo extends Bar, Baz {
+     someProp: string;
+ }

簡單的說,接口更加符合 JavaScript 對象的工作方式,簡單的說明下,當(dāng)出現(xiàn)屬性沖突時(shí):

// 接口擴(kuò)展
interface Sister {
    sex: number;
}

interface SisterAn extends Sister {
    sex: string;
}

// interface SisterAn
// 接口“SisterAn”錯(cuò)誤擴(kuò)展接口“Sister”。
// 屬性“sex”的類型不兼容。
// 不能將類型“string”分配給類型“number”。ts(2430)
// “SisterAn”已聲明,但從未使用過。ts(6196)


// 交叉類型
type Sister1 = {
    sex: number;
}

type Sister2 = {
    sex: string;
}

type SisterAn = Sister1 & Sister2;
// 不報(bào)錯(cuò),此時(shí)的 SisterAn 是一個(gè)'number & string'類型,也就是 never

到此這篇關(guān)于Typescript中 type 與 interface 的區(qū)別的文章就介紹到這了,更多相關(guān)Typescript中 type 與 interface 的區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論