最近在學習TypeScript時,覺得Type跟Interface這兩種定義型別的方式,有種若即若離的關係, 定義型別何時要用type、何時要用Interface呢?自己也無法解釋的很清楚,於是想把在網路上找到的知識, 以及自己的實作做些統整,加深自己的記憶點。
Type 定義型別的一種方法,可採用顯式的定義,也可使用隱式的類型推斷,常用來定義較為簡易的型別類型(較為推薦), 對定義之型別,有較多的操作空間,TypeScript提供了許多工具類型的type供我們使用。可以表示原始類型、聯合類型、元組類型和物件類型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 type Apple = string type Allen ={ year :number ; kind :string ; IQ ?:number ; =>?代表選填 ():string => 可以被執行 [key :string ]:any => 可以接受任何 index new (allen :string ):string => 可以被實例化 readonly weight :number => 只讀屬性 } function test (s:allen ){ console .log ( s.IQ ,s.year , s ()) return new s ('allen' ) } --- type GetType <T,K extends keyof T> = {[S in K]:T[S]} type c = GetType <allen, 'year' > type ExcludeType <T,K extends T> = T extends K ? never : Ttype a = ExcludeType <'year' | 'age' |'now' , 'year' > type Book ={ readonly buyYear :number ; readonly kind :string ; readonly cost :number ; } type ReadonlyRemove <T> = {-readonly [S in keyof T ]:T[S]}type x = ReadonlyRemove <Book >
Interface 用來形容或描述物件的結構或屬性的型別,也因為Js有許多物件結構的描述,較能用來描述這些預設的js行為~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 interface myInterFace{ [propname :string ]:any , name :string , age?:number , say ():string , } interface myInterFace{ gender :string ; } const obj :myInterFace = { name :'123' , age :12 , gender :'12312313123' } class Myclass implements (實現) myInterFace{} interface Myclass extends myInterFace{} interface cake<T,K>{ cost :T, size :K } const a :cake<number ,string > ={ cost :18 , size :"big" }
補充 [key:string|number|symbol] 若建立key必須符合以下型別,不然會ERROR。
Type vs Interface 與interface的差異在於無法重複覆值,沒有overload特性及merging特性,並且不能繼承實作物件與其屬性。 而且語意上也有些需差異,需要多方評估後挑適合的使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 type Allen = {year :number ,height :number } <-顯式定義type Allen = {kind :string } <- Duplicate identifier 'Allen' 無法合併interface Hellen {year :number ,height :number }interface Hellen {kind :string } <- Hellen 屬性中有year,height,kind => merging 合併了interface cake{ cost :string , size :number , match (s :string ):void ; match (s :number ):number ; } function testOne (a :cake):number { return a.match (18 ) } type Point = [number , number ];interface Point { x : number ; y : number ; }
簡單下個結論,就是使用前先思考要定義的是原始的型別,亦或是物件型別,若是物件型別是否需要操作其中的屬性, 還是單純的表示構造屬性,若需要操作就可以考慮type,反之則可以使用interface做為表示~
若有不同的看法,歡迎在下方留言~
TypeScript官網描述 TypeScript DeepDive