亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

TypeScript泛型推斷怎么實現

發布時間:2022-08-17 16:12:40 來源:億速云 閱讀:172 作者:iii 欄目:開發技術

這篇文章主要介紹“TypeScript泛型推斷怎么實現”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“TypeScript泛型推斷怎么實現”文章能幫助大家解決問題。

基礎類型準備

  • 用一個枚舉來定義Animal的類型

enum EAnimalType {
  dog = 'dog',
  cat = 'cat',
  bird = 'bird',
}
  • 定義不同類型的動物有不同的能力類型

type Dog = {
  /** 大叫 */
  shoutLoudly: () => void;
}
type Cat = {
  say: () => void;
}
type Bird = {
  /** 飛 */
  fly: () => void;
}
  • 定義一個動物的映射類型

 type AnimalMap = {
  [EAnimalType.dog]: Dog;
  [EAnimalType.cat]: Cat;
  [EAnimalType.bird]: Bird;
}

最終使用的方式

/**
 * 定義一個工廠,用來創建具體動物的實例
 * @returns 返回動物的實例
 */
function createAnimalFactory<T extends EAnimalType>(): IAnimal<T> {
  // TODO 根據業務具體實現
  return {} as IAnimal<T>;
}
// 根據泛型創建狗狗的實例
const dog = createAnimalFactory<EAnimalType.dog>();
dog.shoutLoudly();
// 根據泛型創建鳥的實例
const bird = createAnimalFactory<EAnimalType.bird>();
bird.fly()

基于Interface的實現 (失敗了)

  • 接著我們創建一個interface 來定義動物基礎接口

export interface IAnimal<T extends EAnimalType> extends IAnimalExtra<T> {
  id: number;   // 編號
  name: string;   // 名稱
  type: T;   // 類型
}

我們看到IAnimal接口繼承了IAnimalExtra接口,我們想的是通過泛型T來動態推導出真實的類型。讓我們來看看IAnimalExtra接口怎么寫

  • IAnimalExtra接口

export type IAnimalExtra<T extends EAnimalType>  {
  [c in keyof AnimalMap[T]]: AnimalMap[T][c];
}

TypeScript泛型推斷怎么實現

我們這樣寫,發現調試控制臺報了很多錯,具體分析了下錯誤,接口不支持這種功能。接著我們嘗試,改成type試一下。

  • 最后用type 去替代 IAnimalExtra

export type IAnimalExtra<T extends EAnimalType> = {
  [c in keyof AnimalMap[T]]: AnimalMap[T][c];
}

我們用type,果然不不錯了,證明我們的思路是對的。乍一看,寫的怎么復雜[c in keyof AnimalMap[T]]: AnimalMap[T][c]; 不要怕,我們先具體分析一下這段代碼,就很好理解了。

  • 先看AnimalMap[T],可以理解從AnimalMap類型中獲取對應的類型,近似js中從對象取值

  • keyof 接受一個Object,生成Object的key的字符串的union(聯合)

  • in 可以遍歷枚舉類型,類似 for...in

整體的功能就是根據泛型T,獲取AnimalMap中的某個類型,遍歷。

  • extends IAnimalExtra<T> 報錯了

TypeScript泛型推斷怎么實現

在我們最終認為可以的情況下,發現有報錯了,內容為【接口只能擴展對象類型或對象類型與靜態已知成員的交集】

所有內容都基于type 實現

在我們嘗試了多次之后,發現Interface怎么也滿足不了需求,接著我們都換成type去試試。

export type IAnimal<T extends EAnimalType> = IAnimalExtra<T> & {
  id: number;   // 編號
  name: string;   // 名稱
  type: T;   // 類型
}

這里我們用了&交叉類型類合并接口的類型。

換成type之后,已能完全滿足我們的需求,能根據泛型推斷出我們想要的類型。

完整Demo

/**
 * 動物枚舉
 */
export enum EAnimalType {
  dog = 'dog',
  cat = 'cat',
  bird = 'bird',
}
type Dog = {
  /** 大叫 */
  shoutLoudly: () => void;
}
type Cat = {
  say: () => void;
}
type Bird = {
  /** 飛 */
  fly: () => void;
}
export type AnimalMap = {
  [EAnimalType.dog]: Dog;
  [EAnimalType.cat]: Cat;
  [EAnimalType.bird]: Bird;
}
export type IAnimalExtra<T extends EAnimalType> = {
  [c in keyof AnimalMap[T]]: AnimalMap[T][c];
}
export type IAnimal<T extends EAnimalType> = IAnimalExtra<T> & {
  id: number;   // 編號
  name: string;   // 名稱
  type: T;   // 類型
}
/**
 * 定義一個工廠,用來創建具體動物的實例
 * @returns 返回動物的實例
 */
function createAnimalFactory<T extends EAnimalType>(): IAnimal<T> {
  // TODO 根據業務具體實現
  return {} as IAnimal<T>;
}
// 根據泛型創建狗狗的實例
const dog = createAnimalFactory<EAnimalType.dog>();
dog.shoutLoudly();
// 根據泛型創建鳥的實例
const bird = createAnimalFactory<EAnimalType.bird>();
bird.fly();

關于“TypeScript泛型推斷怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新河县| 远安县| 修文县| 曲阜市| 通化县| 崇明县| 新绛县| 梁河县| 驻马店市| 那曲县| 扶风县| 金寨县| 行唐县| 娄底市| 双城市| 兴文县| 阿瓦提县| 普宁市| 天水市| 瑞安市| 田阳县| 云南省| 博客| 台中县| 棋牌| 景泰县| 昌都县| 临洮县| 金沙县| 洞口县| 贵溪市| 兴安盟| 多伦县| 黎平县| 凤城市| 疏附县| 丹巴县| 盘山县| 贞丰县| 北安市| 久治县|