您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關TypeScript中的接口和泛型是什么的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
使用 interface 關鍵字來定義數據類型
當存在于較長的數據類型約束時,我們可以通過 type 關鍵字 為類型注解起別名,也可以通過接口來定義
type UserType = { name: string; age?: number }; const user: UserType = { name: "kiki", age: 18, }; interface IUserType { name: string; age?: number } const person: IUserType = { name: 'alice', age: 20 }
interface 和type定義對象都可以為只知道key的類型,不知道具體 key 值的時候,進行類型的定義
interface ILanguage { [index: number]: string; } const language: ILanguage = { 0: "html", 1: "css", 2: "js", }; type Score = { [name: string]: number; } const score: Score = { Chinese: 120, math: 95, Englist: 88, };
定義函數時,interface 和 type 的語法稍有不同
interface ISelfType { (arg: string): string; } type LogType = (arg: string) => string; function print(arg: string, fn: ISelfType, logFn: LogType) { fn(arg); logFn(arg); } function self(arg: string) { return arg; } console.log(print("hello", self, self));
接口可以實現多繼承,繼承后的接口具備所有父類的類型注解
interface ISwim { swimming: () => void; } interface IEat { eating: () => void; } interface IBird extends ISwim, IEat {} const bird: IBird = { swimming() {}, eating() {}, };
交叉類型其實是與的操作,用 & 符號,將接口進行與操作后,實質上需要滿足所有與操作接口的類型注解
interface ISwim { swimming: () => void; } interface IEat { eating: () => void; } type Fish = ISwim | IEat; type Bird = ISwim & IEat; const fish: Fish = { swimming() {}, }; const bird: Bird = { swimming() {}, eating() {}, }; export {}
接口可以通過類使用 implements 關鍵字來實現,類只能繼承一個父類,但是可以實現多個接口
interface ISwim { swimming: () => void } interface IEat { eating: () => void } class Animal {} class Fish extends Animal implements ISwim, IEat { swimming(){} eating(){} } class Person implements ISwim { swimming(){} } function swimAction(iswim: ISwim){ iswim.swimming() } swimAction(new Fish()) swimAction(new Person())
沒有實現接口的類,自然是沒有該接口中的方法
很多時候 interface 和 type 是相同的,但有一個明顯區別在于 interface 可以重復定義,類型注解會累加,而 type 重復定義會報錯
直接把字面量賦值類型給變量時,會對字面量進行類型推導,多出的屬性會報錯
但是將對象的引用賦值的話,會進行 freshness 擦除操作,類型檢測時將多余的屬性擦除,如果依然滿足類型就可以賦值
枚舉類型通過 enum 關鍵字來定義,它和聯合類型實現的功能類似,但是枚舉類型的代碼閱讀性會更強一些
enum Direction { LEFT, RIGHT, TOP, BOTTOM, } function turnDirection(direction: Direction) { switch (direction) { case Direction.LEFT: break; case Direction.RIGHT: break; case Direction.TOP: break; case Direction.BOTTOM: break; default: const foo: never = direction; break; } } turnDirection(Direction.LEFT);
當不確定入參的類型時,可以定義類型注解為泛型,使用的時候再指定具體類型,使用 <> 來進行泛型的定義。
function self<T>(element: T) { return element; } self<string>("alice"); self<number>(2); self<null>(null);
如果沒有定義類型,ts會進行類型推導,有可能并不是我們希望的類型,如以下字符串推導出來不是”string“字符串類型,而是“hello”字面量類型。
當存在多個參數時,在泛型中定義多個即可
function foo<T, E, O>(a: T, b: E, c: O){} foo(1, 'alice', false) foo(['alice'], undefined, null)
在接口中使用泛型,將類型注解寫在接口名后
interface Person<T, E> { name: T; age: E; } const person: Person<string, number> = { name: "alice", age: 20, };
在接口中使用泛型是無法進行類型推導的,使用的時候必須指定具體的類型
除非在接口定義的時候給泛型設置了默認值
interface Book<T = string, E = number> { category: T; price: E; } const book: Book = { category: "nature", price: 88.6, }; const dictionary: Book<number, string> = { category: 1, price: '88' }
類中定義的方式,只是將具體的數據類型替換成了泛型,在類中是可以進行類型推導的
class Point<T> { x: T; y: T; z: T; constructor(x: T, y: T, z: T) { this.x = x; this.y = y; this.z = z; } } new Point("1.55", "2.34", "3.67"); new Point(1.55, 2.34, 3.67);
泛型可以通過繼承來進行類型約束
只需要傳入的參數滿足泛型的條件,即有 length 屬性
interface ILength { length: number; } function getLength<T extends ILength>(element: T) { return element.length; } getLength("alice"); getLength(["alice", "kiki", "lucy"]); getLength({ length: 5 });
接口、枚舉、泛型 這些類型在JavaScript都是沒有的,但在TypeScirpt中都是非常重要的類型注解。
感謝各位的閱讀!關于“TypeScript中的接口和泛型是什么”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。