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

TypeScript?泛型推斷實現(xiàn)示例詳解

 更新時間:2022年08月17日 10:49:59   作者:杰出D  
這篇文章主要為大家介紹了TypeScript?泛型推斷實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

最近做東西都在用ts,有時候?qū)懕容^復(fù)雜的功能,如果不熟悉,類型寫起來還是挺麻煩的。有這樣一個功能,在這里,我們就不以我們現(xiàn)有的業(yè)務(wù)來舉例了,我們還是已Animal舉例,來說明場景。通過一個工廠來創(chuàng)建不同的動物實例。在這里我們借助泛型來實現(xiàn)類型的約束和動態(tài)推到指定類型。

基礎(chǔ)類型準(zhǔn)備

  • 用一個枚舉來定義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;
}

最終使用的方式

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

基于Interface的實現(xiàn) (失敗了)

  • 接著我們創(chuàng)建一個interface 來定義動物基礎(chǔ)接口
export interface IAnimal<T extends EAnimalType> extends IAnimalExtra<T> {
  id: number;   // 編號
  name: string;   // 名稱
  type: T;   // 類型
}

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

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

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

  • 最后用type 去替代 IAnimalExtra
export type IAnimalExtra<T extends EAnimalType> = {
  [c in keyof AnimalMap[T]]: AnimalMap[T][c];
}

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

  • 先看AnimalMap[T],可以理解從AnimalMap類型中獲取對應(yīng)的類型,近似js中從對象取值
  • keyof 接受一個Object,生成Object的key的字符串的union(聯(lián)合)
  • in 可以遍歷枚舉類型,類似 for...in

整體的功能就是根據(jù)泛型T,獲取AnimalMap中的某個類型,遍歷。之后我們專門寫篇文章,介紹下這塊相關(guān)的內(nèi)容。

  • extends IAnimalExtra<T> 報錯了

在我們最終認(rèn)為可以的情況下,發(fā)現(xiàn)有報錯了,內(nèi)容為【接口只能擴展對象類型或?qū)ο箢愋团c靜態(tài)已知成員的交集】

所有內(nèi)容都基于type 實現(xiàn)

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

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

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

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

完整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;   // 類型
}
/**
 * 定義一個工廠,用來創(chuàng)建具體動物的實例
 * @returns 返回動物的實例
 */
function createAnimalFactory<T extends EAnimalType>(): IAnimal<T> {
  // TODO 根據(jù)業(yè)務(wù)具體實現(xiàn)
  return {} as IAnimal<T>;
}
// 根據(jù)泛型創(chuàng)建狗狗的實例
const dog = createAnimalFactory<EAnimalType.dog>();
dog.shoutLoudly();
// 根據(jù)泛型創(chuàng)建鳥的實例
const bird = createAnimalFactory<EAnimalType.bird>();
bird.fly();

結(jié)束語

最近深度使用ts中,有一些感觸,用好類型,前期看著比較費時,但隨著項目的迭代,業(yè)務(wù)的復(fù)雜,對我們后期幫助還是很大的。小伙伴,你們在項目中用ts了嗎?

以上就是TypeScript 泛型推斷實現(xiàn)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于TypeScript 泛型推斷的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Js原型鏈constructor prototype __proto__屬性實例詳解

    Js原型鏈constructor prototype __proto__屬性實例詳解

    這篇文章主要介紹了Js原型鏈constructor prototype __proto__屬性實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • 微信小程序商品到詳情的實現(xiàn)

    微信小程序商品到詳情的實現(xiàn)

    這篇文章主要介紹了微信小程序商品到詳情的實現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 前端取消請求及取消重復(fù)請求方式

    前端取消請求及取消重復(fù)請求方式

    這篇文章主要為大家介紹了前端取消請求及取消重復(fù)請求方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 一文解析Express框架view對象使用

    一文解析Express框架view對象使用

    這篇文章主要介紹了Express框架view對象使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • 微信小程序(十九)radio組件詳細(xì)介紹

    微信小程序(十九)radio組件詳細(xì)介紹

    這篇文章主要介紹了微信小程序radio組件詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • 深入內(nèi)存原理談JS中變量存儲在堆中還是棧中

    深入內(nèi)存原理談JS中變量存儲在堆中還是棧中

    JavaScript中基本類型存儲在堆中還是棧中,百度一下有很多不同的答案,本篇文章就來給大家為此做個詳細(xì)的介紹,需要的朋友可以參考一下
    2021-09-09
  • Promise靜態(tài)四兄弟實現(xiàn)示例詳解

    Promise靜態(tài)四兄弟實現(xiàn)示例詳解

    這篇文章主要為大家介紹了Promise靜態(tài)四兄弟實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Intersection?Observer交叉觀察器示例解析

    Intersection?Observer交叉觀察器示例解析

    這篇文章主要為大家介紹了Intersection?Observer交叉觀察器示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 淺談js中的宏任務(wù)和微任務(wù)

    淺談js中的宏任務(wù)和微任務(wù)

    這篇文章我們主要談一談js中的宏任務(wù)和微任務(wù),JavaScript是一門單線程語言,即一次只能完成一個任務(wù),若有多個任務(wù)要執(zhí)行,則必須排隊按照隊列來執(zhí)行,下面我們就來簡單談?wù)凧avaScript吧,需要的朋友可以參考下面文章內(nèi)容的具體內(nèi)容
    2021-09-09
  • threejs中使用drawbufferss示例詳解

    threejs中使用drawbufferss示例詳解

    這篇文章主要為大家介紹了threejs中使用drawbufferss示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09

最新評論