日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TypeScript类型推论(Type Inference)

發布時間:2023/12/2 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TypeScript类型推论(Type Inference) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

要完全理解類型推論需要完整理解類型上下文,并且理解TS對于是否可以使用類型推論是基于靜態分析完成的。
上下文類型應用在許多地方。常見的例子包括函數調用的參數賦值的右手端位置類型斷言對象和數組的成員,和返回語句。上下文類型還充當最佳公共類型中的候選類型。
TS中需要為每個JS名字規定類型,而名字出現在對應的上下文中則會自動獲得類型,若沒有對應的上下文,這個名字則會自動獲得類型any。

名字:通過聲明語句聲明的名字,例如var、let、const、function a() {}、class A {}、import A from ‘.a’、函數參數等,都會在JS環境中添加一個名字,而TS可以給這個名字指定類型。

在JS中名字的聲明是可以在上面提到的常見例子指定的位置,函數參數調用、賦值右手端位置、對象數組成員、返回語句。

函數調用的參數

interface Cb {(a: number): void; } interface Fn {(cb: Cb): void; }const fn: Fn = function (cb) {}fn(function (a) { // 這里a的類型是numberconsole.log(a + 1) })

因為fn這個名字是類型Fn,而Fn類型的入參是類型Cb,所以在fn使用匿名函數作為入參調用的時候TS可以知道這個匿名函數對應的位置是類型Cb,換句話說匿名函數當前的類型上下文是Cb。而Cb要求入參是number類型,所以推斷出匿名函數的參數a是number類型。

賦值的右手端位置

interface Cb {(a: number): void; }const fn: Cb = function (a) {console.log(a + 1) }

fn是類型Cb,因為Cb要求入參是number類型,所以TS推斷出對應位置匿名函數的入參是number類型。

對象和數組的成員

interface Cb {(a: number): void; } interface Obj {fn: Cb } const obj: Obj = {fn: function (a) {console.log(a + 1)} }

obj是類型Obj,而Obj具有屬性fn是類型Cb。因為Cb要求入參是number類型,所以TS推斷出對象obj.fn右手端對應位置匿名函數的入參是number類型。

返回語句

interface Cb {(a: number): void }interface Fn {(): Cb }const fn: Fn = function () {return (a) => {console.log(a + 1)} }

在這例子里,返回的匿名函數獲得類型上下文Cb,而Cb要求入參是number,所以匿名函數的入參被推斷出是number類型。

上面的幾種類型都可以認為名字出現在了賦值的右手端,而被復制的名字可以給這個值提供對應的類型上下文。

類型斷言

interface Fn {(a: number): void; }const fn = function (a) {console.log(a + 1); } as Fn;

在這里匿名函數賦值給變量fn而fn本身是沒有類型的,所以沒辦法推斷匿名函數的入參a的類型,但是我們使用類型給這個匿名函數指定了類型上下文Fn,讓TS具有了推算參數a的依據,得出參數a是number類型。

小結

類型推斷起作用的條件是名字出現在對應的上下文位置,而這個上下文可以通過賦值操作的左手端提供,也可以使用類型斷言直接提供。這樣TS可以根據對應的類型推斷出對應變量的類型。

一些意外

interface Fn {(a: number): void; }function fn(a) {}let a: Fn = fn

在這個例子里,TS無法推斷出函數fn的參數a是number類型,因為賦值操作提供的類型上下文在右手端,而fn這個函數聲明的位置,并不是右手端。對應的右手端位置并不是函數聲明,而是函數聲明的引用。所以TS無法靜態分析出fn中a的類型。
還有一個原因是fn的使用并不唯一,在這里我們將fn賦值給Fn類型的變量a,我們完全可以將它再賦值給Fn1類型的變量b,所以這種情況下fn中a的類型是由運行時決定的,無法靜態分析出來。

interface Fn {(a: number): void; }function fn(a) {}let a: Fn = fninterface Fn1 {(a: number): void; }let b: Fn1 = fn

這里Fn1要求入參a的類型是string,所以fn的入參a既可能是number也可能是string,只有運行這個函數的時候才能確定知道參數a是什么類型。所以在這個例子中a會自動獲得隱式類型any。

進行如下修改:

interface Fn {(a: number): void; }let a: Fn = function fn(a) {}

在這里fn是一個表達式,并不會再當前環境中新建一個名字fn,換句話說這個fn不會再用在別的地方,并且a這個名字直接出現在了右手端對應位置,所以這個fn函數可以得到類型上下文Fn,從而推斷出參數a的類型是number。

總結

以上是生活随笔為你收集整理的TypeScript类型推论(Type Inference)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。