<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近做東西都在用ts,有時候寫比較複雜的功能,如果不熟悉,型別寫起來還是挺麻煩的。有這樣一個功能,在這裡,我們就不以我們現有的業務來舉例了,我們還是已Animal
舉例,來說明場景。通過一個工廠來建立不同的動物範例。在這裡我們藉助泛型來實現型別的約束和動態推到指定型別。
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
來定義動物基礎介面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]; }
我們這樣寫,發現偵錯控制檯報了很多錯,具體分析了下錯誤,介面不支援這種功能。接著我們嘗試,改成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>
報錯了在我們最終認為可以的情況下,發現有報錯了,內容為【介面只能擴充套件物件型別或物件型別與靜態已知成員的交集】
在我們嘗試了多次之後,發現Interface
怎麼也滿足不了需求,接著我們都換成type去試試。
export type IAnimal<T extends EAnimalType> = IAnimalExtra<T> & { id: number; // 編號 name: string; // 名稱 type: T; // 型別 }
這裡我們用了&
交叉型別類合併介面的型別。
換成type之後,已能完全滿足我們的需求,能根據泛型推斷出我們想要的型別。
/** * 動物列舉 */ 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();
最近深度使用ts中,有一些感觸,用好型別,前期看著比較費時,但隨著專案的迭代,業務的複雜,對我們後期幫助還是很大的。小夥伴,你們在專案中用ts了嗎?
以上就是TypeScript 泛型推斷實現範例詳解的詳細內容,更多關於TypeScript 泛型推斷的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45