TypeScript類型推論與類型斷言實例詳解
一、類型推論
類型推論,顧名思義就是指類型在哪里如何被推斷。在TS語法中,如果有些沒地方有明確指出類型,類型推論就會幫助提供類型,即聲明變量時,不賦給類型,就會觸發(fā)類型推論。
1、最佳通用類型
最佳通用類型就是指,在一個或者多個表達(dá)式中,變量的類型會從這些表達(dá)式中的所有類型來推斷出一個最合適的通用類型。
舉個例子:
let brand = 'YSL' brand = 123
當(dāng)定義一個變量brand,變量brand的類型被推斷為字符串,但是后來修改值為另外一種類型,如number,boolean等,TS就會很貼心的提示不能將其他類型分配給字符串。然而這只是從單個表達(dá)式里面推斷,如果是多個表達(dá)式呢?又會如何推斷呢?例如:
let money = [1, 'yuan', null]
money = [123]
money = ['hello']
money = [null]?
?
money = [{ name: 'ducky' }]//錯誤提示可見,當(dāng)需要從幾個表達(dá)式中推斷類型時候,會使用這些表達(dá)式的類型來推斷出一個最合適的通用類型---稱為最佳通用類型。當(dāng)有多個表達(dá)式時,為了推斷money的類型,必須要考慮所有元素的類型。 這里有三種選擇: number,string和null。 計算通用類型算法會考慮所有的候選類型,并給出一個兼容所有候選類型的類型。那如果想要的類型不在候選名單上,又該如何推論呢?例如:
function Animal() {
console.log('animal');
}
function Food() {
console.log('food');
}
function Fruit() {
console.log('fruit');
}
let target= [new Animal(), new Food(), new Fruit()]如果想讓terget的類型被推斷為People[]類型,但是數(shù)組里的候選類型有三種,沒有People[]類型,這肯定是不能推斷出結(jié)果的。那怎么辦呢?這種情況下,當(dāng)候選類型不能使用的時候,我們必須明確地指出類型:
let target:People[]= [new Animal(), new Food(), new Fruit()]
此時,如果沒有找到最佳通用類型的話,target會被推斷為聯(lián)合數(shù)組類型:(Animal|Food|Fruit)[]
2、上下文類型
上下文類型取決于表達(dá)式的類型和其所處的位置,例如:
window.onclick = function(e) {
console.log(e); //報錯提示
};會出現(xiàn)這樣的報錯提示:[ts] Parameter :'e' implicitly has an 'any' type, but a better type may be inferred from usage.,TS類型檢查器使用window.onclick函數(shù)的類型來推斷右邊函數(shù)表達(dá)式的類型,從而推出e參數(shù)的類型,如果函數(shù)表達(dá)式不是在上下文類型的位置,則參數(shù)e具有any類型。我們知道,any表示任意類型, 可以被任何類型分配,也可以分配給任何類型;任意類型,是所有類型的子類型,當(dāng)被賦予any類型的時候,就意味著跟JS運行一樣了。那這里怎么改呢?既然已經(jīng)提示了e具有any類型,那就明確e的類型為any就好了。一旦這個函數(shù)表達(dá)式有了明確的參數(shù)類型注解,上下文類型就會被忽略。
二、類型斷言
類型斷言是指:當(dāng)不確定一個聯(lián)合類型的變量到底是哪種類型的時候,我們只能訪問這個聯(lián)合類型的所有類型里共有的屬性或者方法,但是有的時候就是需要在還不確定類型的情況下就訪問其中一個類型的屬性和方法。類型斷言可以用來手動指定一個值的類型。
類型斷言不是類型轉(zhuǎn)換,斷言成一個聯(lián)合類型中不存在的類型毫無疑問是不被允許的。
語法:<類型>值或者值 as 類型。
舉個例子:
function getFullName(fullname: string | number): number {
if (fullname.length) {
return fullname.length;
} else {
return fullname.toString().length;
}
}
getFullName('hhhhhhhhh')如上代碼,看上去邏輯好像一點問題也沒有,但是就是會給你報錯Property 'length' does not exist on type 'string | number' 。這個時候,肯定不是換成JS來寫,而是通過類型斷言來讓代碼順利執(zhí)行,改造如下:
function getFullName(fullname: string | number): number {
// if ((<string>fullname).length) {
if (fullname as string) {
return (<string>fullname).length
} else {
return fullname.toString().length
}
}
getFullName('hhhhhhhhh')那么理解下面的代碼,對你來說肯定就是小菜一碟啦~:
let greet: any = 'hello'
let greetLength1: number = (<string>greet).length
let greetLength2: number = (<string>greet).length
console.log(greetLength1);//5
console.log(greetLength2);//5
?
interface Ob1 {
name: string,
}
interface Ob2 {
name: number,
}
let myOb: Ob1 | Ob1 = {
name: '123'
}
let obLength: number = (<string>myOb.name).length
console.log(obLength);//3附:類型別名
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === 'string') {
return n;
} else {
return n();
}
}總結(jié)
到此這篇關(guān)于TypeScript類型推論與類型斷言的文章就介紹到這了,更多相關(guān)TS類型推論與類型斷言內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
《javascript設(shè)計模式》學(xué)習(xí)筆記五:Javascript面向?qū)ο蟪绦蛟O(shè)計工廠模式實例分析
這篇文章主要介紹了Javascript面向?qū)ο蟪绦蛟O(shè)計工廠模式,結(jié)合實例形式分析了《javascript設(shè)計模式》中Javascript面向?qū)ο蠊S模式相關(guān)概念、原理、用法及操作注意事項,需要的朋友可以參考下2020-04-04
微信小程序scroll-view實現(xiàn)左右聯(lián)動
這篇文章主要為大家詳細(xì)介紹了微信小程序scroll-view實現(xiàn)左右聯(lián)動,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
JavaScript 關(guān)鍵字屏蔽實現(xiàn)函數(shù)
JavaScript屏蔽關(guān)鍵字,大概的思路就是去用javascript去替換已有的文本,達(dá)到替換的目的2009-08-08
event.currentTarget與event.target的區(qū)別介紹
event.currentTarget與event.target的區(qū)別想大家在使用的時候不是很在意,本文以測試代碼來講解它門之間的不同2012-12-12

