typescript-類型別名
阿新 • • 發佈:2022-03-29
類型別名
類型別名用來給一個一個型別起一個新名字
簡單例子
type Name = string
type NameResolver = () => string
type NameOrResolver = Name | NameResolver
function getName(n: NameOrResolver):Name {
if (typeof n === 'string') {
return n
}
return n()
}
上例中,我們使用type建立類型別名
類型別名常用語聯合型別
interface和type的區別
不同點
語法上
type
和interface
interface User {
name: string
age: number
sayHello: () => void
sayHi():void
}
type UserType = {
name: string
age: number
sayHello: () => void
sayHi():void
}
定義的型別上
- 介面主要宣告的是函式和物件,並且總是需要引入特定的型別
- 類型別名宣告的可以是任何的資料型別(基本類型別名,聯合型別,元組等型別)
// 介面定義型別檢查 interface Point { x: number y: number } // 介面定義函式 interface SetPoint { (x:number, y: number) : void } // 類型別名定義型別檢查 type PointType = { x: number y : number } // 定義函式 type setPointType = (x:number, y : number) => void // 定義原生型別 type Name = string // 物件 type PartialPointX = {x: number} type PartialPointY = {y: number} // 聯合型別 type PartialPoint = PartialPointX | PartialPointY // 定義元組 type dATA = [number,string]
擴充套件的方式不一樣
- 介面可以使用extends關鍵字來進行擴充套件(這個繼承是包含關係,如果父級有了,子集不可以宣告重複的,會報錯的),或者使用implements來進行實現某個介面
interface A {
T1: string
}
interface B{
T2: string
}
interface C extends A,B{
T1:number
}
- 類型別名也可以進行擴充套件,使用
&
符號進行(這個繼承是合併關係,如果父級有了一個型別,子集還可以宣告,但是型別就是變成&)這個叫做交叉型別
type A = {
T1: string
}
type B = {
T2: string
}
type C = {
T1: number
T4: string
} & A & B
const test: C = {
T1: '1', // Type 'string' is not assignable to type 'never'.
T2: '2',
T4: 'dd'
}
注意,類型別名可以宣告形同屬性為不同型別,但是在型別檢查會型別推導成其他型別,這樣使用可能會導致定義的型別和預期不符合
合併宣告
- 介面可以定義一個名字,後面的介面也可以直接使用這個名字,自動合併所有的宣告,不建議這麼使用,還是extends關鍵字好
interface User2 {
name1: string
}
interface User2 {
age: number
}
const user: User2 = {
name1: 'dd',
age:12
}
- 類型別名不能重複定義相同名字,會直接報錯
例項型別進行賦值
- 介面沒有這個功能
- 類型別名可以使用typeof獲取例項的型別進行賦值
let div = document.createElement('div')
type D = typeof div
型別對映
- 介面沒有這個功能
- 類型別名可以使用in來實現型別對映
type keys = 'firstname' | 'lastname'
type DudeType = {
[key in keys] : string
}
const testss: DudeType = {
firstname: '222',
lastname: '333'
}
最大的不同
- 介面可以被類實現,而類型別名不可以
- 介面是用來表達某個類是否擁有某種能力的,其實這就實現了介面
- 介面可以實現繼承類, 類型別名不可以
相同點
- 都不會出現在編譯結果裡面
- 兩者都可以進行擴充套件
- 都可以用來描述函式和物件