1.類型別名
類型別名(自定義類型):為任意類型起別名。
使用場(chǎng)景:當(dāng)同一類型(復(fù)雜)被多次使用時(shí)待德,可以通過(guò)類型別名君丁,簡(jiǎn)化該類型的使用。
解釋:
(1).使用type關(guān)鍵字來(lái)創(chuàng)建類型別名将宪。
(2).類型別名(比如绘闷,此處的CustomArray),可以是任意合法的變量名稱较坛。
(3).創(chuàng)建類型別名后印蔗,直接使用該類型別名作為變量的類型注解即可。
type CustomArray = (number | string)[]
let arr: CustomArray = [1, 2, 34, '0', '99']
let temp: CustomArray = [1, 2, 34, 'aa', 'ab']
2.函數(shù)類型
函數(shù)的類型實(shí)際上指的是:函數(shù)參數(shù)和返回值的類型丑勤。
為函數(shù)指定類型的兩種方式:
a.單獨(dú)指定參數(shù)华嘹、返回值的類型
b.同時(shí)指定參數(shù)、返回值的類型确封。
(1).單獨(dú)指定參數(shù)、返回值的類型:
function add(num1: number, num2: number): number {
return num1 + num2
}
add(10, 52)
//函數(shù)表達(dá)式寫法
const adds=(num1:number,num2:number):number=>{
return num1 + num2
}
adds(12,90)
(2).為對(duì)象添加類型:
JS中的對(duì)象是由屬性和方法構(gòu)成的再菊,而TS中對(duì)象的類型就是在描述對(duì)象的結(jié)構(gòu)(有什么類型的屬性和方法)爪喘。對(duì)象類型的寫法:
let person: {
name: string
age: number
sayHi(): void
greet(name: string): void
} = {
name: 'liu',
age: 90,
sayHi() {},
greet(name) {}
}
解釋:
(1).直接使用來(lái)描述對(duì)象結(jié)構(gòu)。屬性采用屬性名:類型的形式;方法采用方法名():返回值類型的形式纠拔。
(2).如果方法有參數(shù)秉剑,就在方法名后面的小搭號(hào)中指定參數(shù)類型(比如: greet(name: string): void)。
(3).在一行代碼中指定對(duì)象的多個(gè)屬性類型時(shí)稠诲,使用;(分號(hào))來(lái)分隔侦鹏。
如果一行代碼只指定一個(gè)屬性類型(通過(guò)換行來(lái)分隔多個(gè)屬性類型),可以去掉;(分號(hào))臀叙。
方法的類型也可以使用箭頭函數(shù)形式(比如:{sayHi: () => void })略水。
(3).函數(shù)可選參數(shù)
使用函數(shù)實(shí)現(xiàn)某個(gè)功能時(shí),參數(shù)可以傳也可以不傳劝萤。這種情況下渊涝,在給函數(shù)參數(shù)指定類型時(shí),就用到可選參數(shù)了床嫌。比如跨释,數(shù)組的slice方法,可以slice()也可以slice(1)還可以slice(1厌处,3)鳖谈。
可選參數(shù):在可傳可不傳的參數(shù)名稱后面添加?(問(wèn)號(hào))
注意:可選參數(shù)只能出現(xiàn)在參數(shù)列表的最后,也就是說(shuō)可選參數(shù)后面不能再出現(xiàn)必選參數(shù)
function mySlice(start?: number, end?: number): void {
console.log('起始索引:', start, '結(jié)束索引:', end)
}
mySlice()
mySlice(1)
mySlice(1, 5)
(4).對(duì)象類型(對(duì)象的屬性或方法)
對(duì)象的屬性或方法阔涉,也可以是可選的缆娃,此時(shí)就用到可選屬性了
function myAxios(config: { url: string; method?: string }) {}
myAxios({
url: ''
})
可選屬性的語(yǔ)法與函數(shù)可選參數(shù)的語(yǔ)法一致捷绒,都使用?(問(wèn)號(hào))來(lái)表示。
3.接口
當(dāng)一個(gè)對(duì)象類型被多次使用時(shí)龄恋,一般會(huì)使用接口(interface)來(lái)描述對(duì)象的類型疙驾,達(dá)到復(fù)用的目的。
解釋:
(1)使用interface關(guān)鍵字來(lái)聲明接口郭毕。
(2)接口名稱(比如它碎,此處的IPerson) ,可以是任意合法的變量名稱显押。
(3)聲明接口后扳肛,直接使用接口名稱作為變量的類型。
(4)因?yàn)槊恳恍兄挥幸粋€(gè)屬性類型乘碑,因此挖息,屬性類型后沒(méi)有;(分號(hào))。
// 聲明一個(gè)接口
interface IPerson {
name: string
age: number
sayHi(): void
}
let person: IPerson = {
name: '劉老師',
age: 18,
sayHi() {}
}
let person1: IPerson = {
name: 'jaak',
age: 16,
sayHi() {}
}
interface(接口)和type(類型別名)的對(duì)比:
相同點(diǎn):都可以給對(duì)象指定類型兽肤。
不同點(diǎn):
接口套腹,只能為對(duì)象指定類型。
類型別名资铡,不僅可以為對(duì)象指定類型电禀,實(shí)際上可以為任意類型指定別名。
//類型別名
type IPerson = {
name: string
age: string
sayHi(): void
}
let person: IPerson = {
name: '劉老師',
age: '18',
sayHi() {}
}
如果兩個(gè)接口之間有相同的屬性或方法笤休,可以將公共的屬性或方法抽離出來(lái)尖飞,通過(guò)繼承來(lái)實(shí)現(xiàn)復(fù)用。比如店雅,這兩個(gè)接口都有x政基、y兩個(gè)屬性,重復(fù)寫兩次闹啦,可以沮明,但很繁瑣。
//接口繼承
interface Point2D {
x: number
y: number
}
interface Point3D extends Point2D {
z: number
}
let p3: Point3D = {
x: 90,
y: 30,
z: 87
}
console.log(p3, 'p3')
解釋:
(1).使用extends(繼承)關(guān)鍵字實(shí)現(xiàn)了接口Point3D繼承Point2D窍奋。
(2). 繼承后珊擂,Point3D就有了Point2D的所有屬性和方法(此時(shí),Point3D同時(shí)有x费变、y摧扇、z三個(gè)屬性)。
4.元祖
場(chǎng)景:在地圖中挚歧,使用經(jīng)緯度坐標(biāo)來(lái)標(biāo)記位置信息扛稽。
可以使用數(shù)組來(lái)記錄坐標(biāo),那么滑负,該數(shù)組中只有兩個(gè)元素在张,并且這兩個(gè)元素都是數(shù)值類型用含。
元祖類型是另一種類型的數(shù)組,它確切的知道包含多少個(gè)元素 以及特定索引對(duì)應(yīng)的類型帮匾。
let position:[number,number]=[39.2343,11213.22]
5.類型推論
在TS中啄骇,某些沒(méi)有明確指出類型的地方,TS的類型推論機(jī)制會(huì)幫助提供類型瘟斜。
換句話說(shuō):由于類型推論的存在缸夹,這些地方,類型注解可以省略不寫!
發(fā)生類型推論的2種常見(jiàn)場(chǎng)景:
聲明變量并初始化時(shí)
決定函數(shù)返回值時(shí)
注意:如果聲明變量但沒(méi)有立即初始化值螺句,此時(shí) 還必須手動(dòng)添加類型注釋
let a:number
a=19
function add_fun(num1: number, num2: number){
return num1 + num2
}
注意:這兩種情況下虽惭,類型注解可以省略不寫!
推薦:能省略類型注解的地方就省略(偷懶,充分利用TS類型推論的能力蛇尚,提升開(kāi)發(fā)效率)芽唇。
技巧:如果不知道類型,可以通過(guò)鼠標(biāo)放在變量名稱上取劫,利用VSCode的提示來(lái)查看類型匆笤。
6.類型斷言
有時(shí)候開(kāi)發(fā)人員會(huì)比TS 更加明確一個(gè)值的類型,此時(shí)谱邪,可以使用類型斷言來(lái)指定更具體的類型炮捧。
例如:a標(biāo)簽
注意: getElementByld方法返回值的類型是HTMLElement,該類型只包含所有標(biāo)簽公共的屬性或方法虾标,不包含a標(biāo)簽特有的href等屬性寓盗。
因此灌砖,這個(gè)類型太寬泛(不具體)璧函,無(wú)法操作href等a標(biāo)簽特有的屬性或方法。
解決方式:這種情況下就需要使用類型斷言指定更加具體的類型基显。
解釋:
(1).使用as關(guān)鍵字實(shí)現(xiàn)類型斷言蘸吓。
(2). 關(guān)鍵字as后面的類型是一個(gè)更加具體的類型(HTMLAnchorElement是HTMLElement 的子類型)。3.通過(guò)類型斷言撩幽,aLink的類型變得更加具體库继,這樣就可以訪問(wèn)a標(biāo)簽特有的屬性或方法了。
另一種語(yǔ)法窜醉,使用<>語(yǔ)法宪萄,這種語(yǔ)法形式不常用知道即可:
const aLink = document.getElementById('aLink') as HTMLAnchorElement
aLink.href=''
7.字面量類型
使用模式:字面量類型配合聯(lián)合類型一起使用。使用場(chǎng)景:用來(lái)表示一組明確的可選值列表榨惰。
比如拜英,在貪吃蛇游戲中,游戲的方向的可選值只能是上琅催、下居凶、左虫给、右中的任意一個(gè)。
function changeDirection(direction: 'up'l ' down’l 'left' l 'right'){
console.log(direction)
}
解釋:參數(shù)direction的值只能是up/down/left/right中的任意一個(gè)侠碧。優(yōu)勢(shì):相比于string 類型抹估,使用字面量類型更加精確、嚴(yán)謹(jǐn)弄兜。
function changeDireciton(direction: 'up' | 'down' | 'left' | 'right') {
console.log(direction)
}
changeDireciton('up')
8.枚舉
枚舉的功能類似于字面量類型+聯(lián)合類型組合的功能药蜻,也可以表示一組明確的可選值。
心
枚舉:定義一組命名常量挨队。它描述一個(gè)值谷暮,該值可以是這些命名常量中的一個(gè)。
enum Direction { Up,Down,Left盛垦,Right }
function changeDirection(direction: Direction) iconsole.log(direction)
}
解釋:
使用enum關(guān)鍵字定義枚舉湿弦。
約定枚舉名稱、枚舉中的值以大寫字母開(kāi)頭腾夯。
枚舉中的多個(gè)值之間通過(guò)颊埃,(逗號(hào))分隔。
定義好枚舉后蝶俱,直接使用枚舉名稱作為類型注解宏所。
//定義枚舉
enum Direction{
Up,
Down,
Left,
Right
}
function changeDireciton(direction:Direction ) {
console.log(direction)
}
changeDireciton(Direction.Up)
注意:形參direction 的類型為枚舉Direction伐债,那么,實(shí)參的值就應(yīng)該是枚舉Direction成員的任意一個(gè)。訪問(wèn)枚舉成員:
enum Direction { Up,Down窃植,Left,Right }
function changeDirection(direction: Direction)iconsole.log(direction)
changeDirection(Direction. Up)
解釋:類似于JS中的對(duì)象志电,直接通過(guò)點(diǎn)(.)語(yǔ)法訪問(wèn)枚舉的成員骇笔。
問(wèn)題:我們把枚舉成員作為了函數(shù)的實(shí)參,它的值是什么呢?
enum member) Direction. Up = 0
changeDirection(Direction. Up)
解釋:通過(guò)將鼠標(biāo)移入Direction.Up竿拆,可以看到枚舉成員Up的值為0宙拉。注意:枚舉成員是有值的,默認(rèn)為:從0開(kāi)始自增的數(shù)值丙笋。
心
我們把谢澈,枚舉成員的值為數(shù)字的枚舉,稱為:數(shù)字枚舉御板。
當(dāng)然锥忿,也可以給枚舉中的成員初始化值。
enum Direction { Up =10怠肋,Down,Left敬鬓,Right }
enum Direction { Up = 2,Down = 4,Left = 8列林,Right = 16}
字符串枚舉:枚舉成員的值是字符串瑞你。enum Direction {
Up = 'URP',Down = ''DOWN',Left = 'LEFT',Right = 'RIGHT'}
注意:字符串枚舉沒(méi)有自增長(zhǎng)行為,因此希痴,字符串枚舉的每個(gè)成員必須有初始值者甲。
//字符串枚舉
enum DirectionStr {
Up = 'up',
Down = 'down',
Left = 'left',
Right = 'right'
}
枚舉是TS為數(shù)不多的非JavaScript類型級(jí)擴(kuò)展(不僅僅是類型)的特性之一。
因?yàn)?其他類型僅僅被當(dāng)做類型砌创,而枚舉不僅用作類型虏缸,還提供值(枚舉成員都是有值的)。
也就是說(shuō)嫩实,其他的類型會(huì)在編譯為JS代碼時(shí)自動(dòng)移除刽辙。但是,枚舉類型會(huì)被編譯為JS代碼!
說(shuō)明:枚舉與前面講到的字面量類型+聯(lián)合類型組合的功能類似甲献,都用來(lái)表示一組明確的可選值列表宰缤。
一般情況下,推薦使用字面量類型+聯(lián)合類型組合的方式晃洒,因?yàn)橄啾让杜e慨灭,這種方式更加直觀、簡(jiǎn)潔球及、高效氧骤。
- any類型
原則:不推薦使用any!這會(huì)讓TypeScript變?yōu)椤癆nyScript”(失去TS類型保護(hù)的優(yōu)勢(shì))。因?yàn)楫?dāng)值的類型為any時(shí)吃引,可以對(duì)該值進(jìn)行任意操作筹陵,并且不會(huì)有代碼提示。
let obj: any = { x:0 }
obj.bar = 100
obj()
const n: number = obj
解釋:以上操作都不會(huì)有任何類型錯(cuò)誤提示镊尺,即使可能存在錯(cuò)誤!
盡可能的避免使用any類型朦佩,除非臨時(shí)使用any來(lái)“避免”書寫很長(zhǎng)、很復(fù)雜的類型!
其他隱式具有any類型的情況:
1聲明變量不提供類型也不提供默認(rèn)值
⒉函數(shù)參數(shù)不加類型鹅心。注意:因?yàn)椴煌扑]使用any 吕粗,所以纺荧,這兩種情況下都應(yīng)該提供類型!