??個(gè)人主頁:不叫貓先生
???♂?作者簡(jiǎn)介:前端領(lǐng)域新星創(chuàng)作者、華為云享專家、阿里云專家博主,專注于前端各領(lǐng)域技術(shù),共同學(xué)習(xí)共同進(jìn)步,一起加油呀!
??系列專欄:vue3從入門到精通、TypeScript從入門到實(shí)踐
??個(gè)人簽名:不破不立
專欄介紹
TypeScript從入門到實(shí)踐專欄是博主在學(xué)習(xí)和工作過程中的總結(jié),內(nèi)容會(huì)不斷進(jìn)行精進(jìn),實(shí)用性非常強(qiáng),歡迎訂閱哦,學(xué)會(huì)TS不迷路。
TS系列 | 標(biāo)題 |
---|---|
基礎(chǔ)篇 | TS入門(一) |
基礎(chǔ)篇 | TS類型聲明(二) |
基礎(chǔ)篇 | TS接口類型(三) |
基礎(chǔ)篇 | TS交叉類型&聯(lián)合類型(四) |
基礎(chǔ)篇 | TS類型斷言(五) |
基礎(chǔ)篇 | TS類型守衛(wèi)(六) |
進(jìn)階篇 | TS函數(shù)重載(七) |
進(jìn)階篇 | TS泛型(八) |
進(jìn)階篇 | TS裝飾器(九) |
前言
本文主要講解TypeScript的基本數(shù)據(jù)結(jié)構(gòu),主要包括JS基本數(shù)據(jù)類型以及TS特有的數(shù)據(jù)類型。
- JS基本數(shù)據(jù)類型: string、number、null、undefined、boolean、array
- TS特有的數(shù)據(jù)類型:tuple(元祖)、enum(枚舉)、any、unknow、never
注意: node
不能直接執(zhí)行ts文件,需要先將ts編譯成js,然后再執(zhí)行js
一、 string、number、null、undefined、boolean類型聲明
- JS普通寫法如下:
let myName = "zhangsan";
let count = 1;
let a = null;
let b = undefined;
let visiable = false;
- TS寫法如下:
不能更改它們的變量類型,否則會(huì)直接報(bào)錯(cuò)
let myName: String = "zhangsan";
let count: Number = 1;
let a: null = null;
let b: undefined = undefined;
let visiable: boolean = false;
- 編譯成JS后如下:
var myName = "zhangsan";
var count = 1;
var a = null;
var b = undefined;
var visiable = false;
- 編譯后為什么let會(huì)變成var呢?
es6是規(guī)范 但是還有很多瀏覽器不支持 所以編譯完之后都是轉(zhuǎn)義成es5, es5沒有l(wèi)et。并且需要在tsconfig.json
中配置如下:
{
"compilerOptions": {
"target": "ES5",
}
}
在這里插入代碼片
- 錯(cuò)誤示范:
let myName: String = "zhangsan";
myName = true;//Error:Type 'true' is not assignable to type 'String'.
二、 array、tuple(元組)
JS數(shù)組和TS數(shù)組之間的區(qū)別
JS中的數(shù)組可以是字符串、數(shù)字等其他類型的數(shù)據(jù),而TS中的數(shù)組是純數(shù)字類型(number
)的集合,如果在TS中定義包含多個(gè)類型的數(shù)組,那就是元組。
JS寫法如下:
let arr = ['語文','數(shù)學(xué)']
TS聲明數(shù)組有多種方式,具體如下:
(1)數(shù)組的數(shù)據(jù)類型一致
- Array<>:聲明一個(gè)數(shù)組,數(shù)組類型為
<>
中定義的類型,比如:Array<string>
//聲明一個(gè)數(shù)組,并且數(shù)組中的數(shù)據(jù)類型都是字符串
let arr:Array<string> = ['語文','數(shù)學(xué)']
let arrA:string[] = ['語文','數(shù)學(xué)']
//注意:數(shù)組這樣寫會(huì)報(bào)錯(cuò)
let arr:Array= ['語文','數(shù)學(xué)'] //error
- string[]:聲明一個(gè)數(shù)組,數(shù)組類型為
[]
前定義的類型,比如number[]
let arr:string[] = ['a']
(2)數(shù)組的數(shù)據(jù)類型不一致
- 聯(lián)合數(shù)據(jù)聲明:比如
(string|number)[]
,聲明一個(gè)數(shù)組,數(shù)組類型為字符串、數(shù)字。數(shù)組中數(shù)據(jù)的類型可以不隨定義的類型位置的限定。
let arr:(string|number)[] = ['a',1]
let arrB:(string|number)[] = ['a',1,1,'b']
let arrC:(string|number)[] = [1,1,'b','c']
let arrC:(string|number)[] = [1,1]
//或者這樣聲明
let arrD: Array<string | number> = [1, 12, 'a']
(3)數(shù)組的數(shù)據(jù)類型任意
let arr:any[] = ['a',1,true,null]
//或者這樣聲明
let arrE:Array<any> = ['a',1,true,null]
(4)限制類型和長(zhǎng)度的元祖數(shù)組
tuple(元祖):是固定數(shù)量的不同類型的元素的組合,比如[number, string]
。數(shù)組中數(shù)據(jù)的位置、類型以及個(gè)數(shù)必須要和聲明的類型、聲明類型的位置、聲明類型的個(gè)數(shù)保持一致,否則就會(huì)報(bào)錯(cuò)。
let tupleArr: [number, string] = [1, '數(shù)學(xué)']
let tupleArrA: [number, string] = [1, '數(shù)學(xué)',1]//error
let tupleArrA: [number, string] = ['數(shù)學(xué)',1]//error
三、enum(枚舉)
枚舉主要分為數(shù)字類型枚舉、字符串類型枚舉、異構(gòu)。
語法:enum
+ 變量名,意思是定義了一個(gè)叫做“變量名”的枚舉類型
優(yōu)點(diǎn):定義一些常量,可以清晰地表達(dá)意圖或創(chuàng)建一組有區(qū)別的用例。
(1)數(shù)字型枚舉
- 含義:枚舉成員都是number類型,如果沒有對(duì)枚舉對(duì)象中的枚舉成員賦值,那么會(huì)默認(rèn)從枚舉對(duì)象中的第一個(gè)枚舉成員的值是0,并依次遞增。
- 具有以下特點(diǎn):
- 反向映射
- 枚舉成員的值可以不用初始化
enum Value {
A,
B,
C,
D,
E,
F
}
let value: Value = Value['A']
let valueName = Value[0]
console.log(value)//0
console.log(valueName)//A
以上可知,我們既可以取到枚舉成員的屬性名,也能取到枚舉成員的屬性值,它們之間是相互映射的。
- 修改枚舉成員的默認(rèn)值
enum Value {
A,
B,
C=8,
D,
E,
F
}
let value: Value = Value['E']
let valueNameA = Value[8]
let valueNameB = Value[9]
console.log(value)//10
console.log(valueNameA)//C
console.log(valueNameB)//D
我們可以看到我們改變枚舉成員的默認(rèn)值的時(shí)候,后面枚舉成員的默認(rèn)值也隨著前面的改變而改變。我們來看一下上面編譯成JS后的樣子,具體如下所示:
var Valuedemo;
(function (Valuedemo) {
Valuedemo[Valuedemo["A"] = 0] = "A";
Valuedemo[Valuedemo["B"] = 1] = "B";
Valuedemo[Valuedemo["C"] = 8] = "C";
Valuedemo[Valuedemo["D"] = 9] = "D";
Valuedemo[Valuedemo["E"] = 10] = "E";
Valuedemo[Valuedemo["F"] = 11] = "F";
})(Valuedemo || (Valuedemo = {}));
var valueA = Valuedemo['A'];
var valueNameA = Valuedemo[8];
console.log(valueA);
console.log(valueNameA);
(2)字符串類型枚舉
含義:枚舉成員類型都是字符串
需要注意以下幾個(gè)方面:
-
字符串枚舉沒有反向映射,如果進(jìn)行反向映射的話,取得的值時(shí)
undefined
; - 字符串枚舉沒有遞增,需要對(duì)每一個(gè)字符串枚舉類型成員進(jìn)行賦值,即必須具有初始化表達(dá)式
enum StringValue {
A = 'A',
B = 'B',
C = 'C',
D = 'D',
E = 'E',
F = 'f'
}
let stringValueVal = StringValue['A']
console.log(stringValueVal)//A
以下是錯(cuò)誤示范,不能對(duì)字符串類型枚舉進(jìn)行反向映射
let stringValueNameA = StringValue['f']
let stringValueNameB = StringValue[0]
console.log(stringValueNameA)//undefined
console.log(stringValueNameB)//undefined
(3)異構(gòu)
含義:枚舉類型包括字符串類型和數(shù)字類型
注意:含有字符串值成員的枚舉中不允許使用計(jì)算值,具體意思就是當(dāng)枚舉對(duì)象中存在有value
是字符串的枚舉成員的時(shí)候,不能將其他枚舉成員的value
設(shè)置為計(jì)算值。
enum Enum {
A,
B,
C = 'C',
D = 'd',
E = 9,
F
}
console.log(Enum['10'])//F
console.log(Enum['C'])//C
console.log(Enum['A'])//o
console.log(Enum['d'])//undefined
console.log(Enum['D'])//d
console.log(Enum[9])//E
console.log(Enum[0])//A
上面的TS編譯成JS后的樣子如下所示:
var Enum;
(function (Enum) {
Enum[Enum["A"] = 0] = "A";
Enum[Enum["B"] = 1] = "B";
Enum["C"] = "C";
Enum["D"] = "d";
Enum[Enum["E"] = 9] = "E";
Enum[Enum["F"] = 10] = "F";
})(Enum || (Enum = {}));
我們用普通方法來實(shí)現(xiàn)異構(gòu)枚舉,demo如下所示:
enum Enum {
A,
B,
C = 'C',
D = 'D',
E = 9,
F
}
怎么實(shí)現(xiàn)以上的枚舉呢?具體如下:
let Enum;
(function (Enum) {
Enum[0] = 'A';
Enum[1] = 'B';
Enum[9] = 'E';
Enum[10] = 'F';
Enum['A'] = 0;
Enum['B'] = 1;
Enum['C'] = 'C';
Enum['D'] = 'D';
Enum['E'] = 9;
Enum['F'] = 10;
})(Enum || (Enum = {}))
以上我們看出依然是數(shù)字類型的枚舉成員可以進(jìn)行反向映射,字符串類型的枚舉成員不能反向映射。
注意以下是錯(cuò)誤用法,因?yàn)楹凶址党蓡T的枚舉中不允許使用計(jì)算值
enum Enum {
A,
B = 3*6,
C = 'C',
D = 'd',
E = 9,
F
}
(4)枚舉成員的值的兩種形式-計(jì)算值和常量
枚舉對(duì)象中成員的value
有兩種形式,計(jì)算值或者常量,怎么區(qū)分是計(jì)算值和常量呢?我們可以通過枚舉成員表達(dá)式來判斷,只要是枚舉成員是表達(dá)式則為常量。枚舉成員表達(dá)式的判斷條件如下:
- 枚舉表達(dá)式字面量(主要是字符串字面量或數(shù)字字面量)
- 對(duì)之前定義的常量枚舉成員的引用
- 帶括號(hào)的常量枚舉表達(dá)式
- 一元運(yùn)算符 ++、 –
- 常量枚舉表達(dá)式是二元運(yùn)算符 + 、-、*、/、%、<<、>>、&、|、^的操作對(duì)象。注意:如果求值后值為NaN或Infinity,那么會(huì)在編譯階段報(bào)錯(cuò)。
常量demo如下:
enum constantEnum{
num, //枚舉表達(dá)式字面量
age = num, //引用常量枚舉成員
count = 2 << 1, //枚舉表達(dá)式字面量參與二元運(yùn)算符
numB = 30 | 2,
numA = 10 + 29
}
計(jì)算值demo如下所示:
let name = 'zhsngasn'
enum calculationEnum{
nameLen = name.length,
num = Math.random() * 10
}
四、any(任意類型)
聲明變量類型為any
時(shí)
- 編譯時(shí)會(huì)繞過所有類型的檢測(cè),直接通過編譯階段的檢查
- 可以任意訪問屬性的方法和屬性
-
any
類型可以賦值給任意類型 - 如果變量初始沒有定義類型,默認(rèn)為
any
;經(jīng)過賦值后,TS會(huì)根據(jù)賦值類型來標(biāo)識(shí)變量的類型
let anyValue: any = 1;
//修改變量類型
anyValue = true;
//賦值給任意類型,比如boolean
let booleanValue: boolean = anyValue;
console.log(booleanValue)//true
any在使用過程中就像一個(gè)潘多拉魔盒,即使使用了斷言,也喪失了在靜態(tài)類型檢查階段發(fā)現(xiàn)錯(cuò)誤的可能性。
五、unknow(未知類型)
聲明變量類型為unknow
時(shí)
- 安全性更高
- 它用于描述類型不確定的變量,這與
any
類型相似,但更安全,因?yàn)閷?duì)未知值做任何事情都是不合法的 -
unknown
類型只能賦值給any
和unknown
類型,any類型可以賦值給任意類型 -
unknown
,never
都不允許執(zhí)行變量的方法以及訪問內(nèi)部屬性 - 在
unknown
沒有被斷言或細(xì)化到一個(gè)確切類型之前,unknown
不可以賦值給其它類型,除了它自己和any
外,當(dāng)然也都是不允許在其上進(jìn)行任何操作的。
let unknownValue: unknown;
//對(duì)變量進(jìn)行任意賦值
unknownValue = true;
unknownValue = 'sss';
unknownValue = 1;
//賦值給unknown類型的變量
let testValue1: unknown = unknownValue;
//賦值給any類型的變量
let testValue2: any = unknownValue;
錯(cuò)誤示范:
//賦值給boolean類型的變量,報(bào)錯(cuò),因?yàn)閡nknown類型只能賦值給unknown、any
let testValue3: boolean = unknownValue;//報(bào)錯(cuò)
雖然可以對(duì)unknown
類型的變量進(jìn)行任意賦值,但是卻不能執(zhí)行任何操作,如何解決這個(gè)問題呢?可以縮小unknown
類型。具體如下所示:
type func = ()=> unknow
let test = func();
if(test instanceof func){
//執(zhí)行邏輯
}
我們可以用斷言縮小未知范圍或者可以用instanceof
來縮小變量的類型,強(qiáng)制讓ts編譯器相信我們?cè)谧鍪裁床僮?/p>
六、void(空類型)
聲明對(duì)象類型為void
時(shí)
- 返回為空值
function func(): void { }
聲明一個(gè)變量為void
時(shí)
-
只能將它賦值為 undefined 和 null,因此在定義函數(shù)的返回值為
void
時(shí),也可return undefined/null
let voidValue1: void = undefined;
let voidValue2: void = null;
七、never(不存在的值類型)
never
類型表示永不存在的值的類型。具有以下特點(diǎn):文章來源:http://www.zghlxwxcb.cn/news/detail-806933.html
-
never
類型是所有類型的子類型,即never
類型可以賦值給任何類型。 - 其他任何類型均不是
never
類型的子類型,即其他類型均不可賦值給never
類型,除了never本身。即使any類型也不可以賦值給never類型。 - 返回類型為
never
的函數(shù)中,其終點(diǎn)必須是不可執(zhí)行的,例如函數(shù)過程中拋出了錯(cuò)誤或者存在死循環(huán)。 - 變量也可以聲明為
never
類型,但其不能被賦值
設(shè)置變量類型為never
,表示永遠(yuǎn)不能執(zhí)行完或者永遠(yuǎn)Error,具體示例如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-806933.html
- 函數(shù)中出現(xiàn)了死循環(huán),永遠(yuǎn)不能執(zhí)行完,因此其函數(shù)類型為:() => never
function infiniteLoop(): never {
while (true) { }
return 'over'
}
-
函數(shù)中出現(xiàn)報(bào)錯(cuò),不會(huì)執(zhí)行到
return over
,因此其函數(shù)類型為:() => never
function errFunc(): never {
throw new Error()
return 'over'
}
到了這里,關(guān)于【TypeScript】TS類型聲明(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!