【前端】你好,我叫TypeScript 01──數(shù)據(jù)類型
前言
TypeScript是強(qiáng)類型語言,所以相比于JavaScript而言有著更強(qiáng)的語言規(guī)范約束能力,能夠讓我們的代碼可讀性更高。同時(shí)可以在編譯過程中進(jìn)行錯(cuò)誤校驗(yàn),提升了我們代碼的開發(fā)效率。
1.什么是Typescript?
TypeScript并不是一門新的編程語言,它是Javscript的超集,即在JavaScript語言的基礎(chǔ)上添加了語言約束:可選的靜態(tài)類型和基于類的面向?qū)ο缶幊?。其?shí)就是添加了靜態(tài)類型檢查,有了約束可以讓我們?cè)陂_發(fā)過程中減少錯(cuò)誤代碼的書寫。
TypeScript和JavaScript的關(guān)系如下:
TypeScript和JavaScript的區(qū)別:
2.兩分鐘上手TS開發(fā)
“工欲行其事,必先利其器”,說的就是在做事情之前,要做好所有的準(zhǔn)備。同樣的,我們要學(xué)習(xí)TS開發(fā),必須先安裝語言環(huán)境和編輯器工具。
安裝TypeScript
有兩種方式可以獲取TypeSscript工具:
- 通過NPM進(jìn)行安裝
- 安裝VScode的TypeScript插件
(1)NPM安裝:
- npm install -g typescript
(2)驗(yàn)證TS安裝
- tsc -v
- # Version 4.2.4
(3)構(gòu)建TS文件 在編輯器中構(gòu)建一個(gè)TS文件test.ts:
- function addNum(num1:num,num2:num){
- return num1 + num2;
- }
- console.log(addNum(1,2));
- //3
(4)編譯代碼:
- tsc test.ts
編譯得到JS代碼:
- "use strict";
- function addNum(num1, num2) {
- return num1 + num2;
- }
- console.log(addNum(1, 2));
3.基礎(chǔ)類型
3.1 Boolean類型
只有兩個(gè)值:true和false。
- let isTrue: boolean = true;
3.2 Number類型
所有的數(shù)字都是浮點(diǎn)型,支持二進(jìn)制、八進(jìn)制、十進(jìn)制以及十六進(jìn)制字面量。
- // 數(shù)字類型,所有數(shù)字都是浮點(diǎn)型
- let decLiteral: number = 10;
- let hexLiteral: number = 0xf00d;
3.3 String類型
TS可以使用雙引號(hào)( ")或單引號(hào)(')表示字符串。
- // 字符串,表示文本數(shù)據(jù)類型
- let username: string = "yichuan";
- let like: string = `${yichuan} + FE`;
3.4 Array類型
數(shù)組操作有兩種方式可以聲明:
- 可以在元素類型后面接上 [],表示由此類型元素組成的一個(gè)數(shù)組。
- 使用數(shù)組泛型,Array<元素類型>。
- let list: number[] = [1, 2, 3];
- let list: Array<number> = [1, 2, 3];
3.5 Tuple類型
元組類型允許表示一個(gè)已知元素?cái)?shù)量和類型的數(shù)組,各元素的類型不必相同。
- // 元組
- let tuple: [string,number];
- tuple = ["wenbo",1];
TS元組和數(shù)組其實(shí)大致一樣,唯一的區(qū)別就是數(shù)組中的元素類型必須相同,而元組可以存儲(chǔ)不同類型的元素。甚至可以說元組是any類型的數(shù)組。
3.6 Enum類型
enum類型是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型的一個(gè)補(bǔ)充。枚舉類型提供的一個(gè)便利是你可以由枚舉的值得到它的名字。
- // 枚舉
- // 默認(rèn)情況下,枚舉的元素編號(hào)是從0開始,也可以進(jìn)行手動(dòng)編號(hào)。
- enum Color {Red, Green, Blue};
- let c:Color = Color.Red;
3.7 Any類型
any表示任意類型。有時(shí)候,我們會(huì)想要為那些在編程階段還不清楚類型的變量指定一個(gè)類型。
- // Any
- let notSure:any = 100.002;
- notSure.toFixed();
- let list3:any[] = ["zhaoshun","male",12];
其實(shí),any類型是類型系統(tǒng)的頂級(jí)類型,因?yàn)槿魏晤愋投細(xì)w結(jié)于any類型,是不是很自由。自由過了火,一個(gè)不恰當(dāng)?shù)谋扔鳎琂S是any類型的TS,允許對(duì)any類型的值進(jìn)行各種操作,而無需編譯校驗(yàn)。
3.8 Void類型
void類型它表示沒有任何類型。當(dāng)一個(gè)函數(shù)沒有返回值時(shí),你通常會(huì)見到其返回值類型是 void。
聲明一個(gè)void類型的變量沒有什么大用,因?yàn)槟阒荒転樗x予null和undefined。
- function showName():void {
- console.log("your name is wenbo");
- }
- // 聲明一個(gè)void類型的變量
- let unusable: void = undefined;
3.9 Null 和 Undefined
TypeScript里,undefined和null兩者各自有自己的類型分別叫做undefined和null。默認(rèn)情況下null和undefined是所有類型的子類型,可以把 null和undefined賦值給number類型的變量。
- let u: undefined = undefined;
- let n: null = null;
但是,當(dāng)指定了--strictNullChecks標(biāo)記,null和undefined只能賦值給void和它們各自。
3.10 Object
object表示非原始數(shù)據(jù)類型(除number,string,boolean,symbol,null或undefined之外的類型)。
- declare function create(o: object | null): void;
- create({ prop: 0 }); // OK
- create(null); // OK
- create(42); // Error
- create("string"); // Error
- create(false); // Error
- create(undefined); // Error
3.11 Never
never類型表示的是那些永不存在的值的類型。
never類型是任何類型的子類型,也可以賦值給任何類型;然而,沒有類型是never的子類型或可以賦值給never類型(除了never本身之外)。即使 any也不可以賦值給never。
- // 返回never的函數(shù)必須存在無法達(dá)到的終點(diǎn)
- function error(message: string): never {
- throw new Error(message);
- }
- // 推斷的返回值類型為never
- function fail() {
- return error("Something failed");
- }
- // 返回never的函數(shù)必須存在無法達(dá)到的終點(diǎn)
- function infiniteLoop(): never {
- while (true) {
- }
- }
3.12 Unknown 類型
任何類型都可以被歸為unknow類型,因此unknow也是ts類型中的頂級(jí)類型。
- let value: unknown;
- value = true; // OK
- value = 18; // OK
- value = "yichuan"; // OK
- value = []; // OK
- value = {}; // OK
- value = Math.random; // OK
- value = null; // OK
- value = undefined; // OK
- value = new TypeError(); // OK
- value = Symbol("type"); // OK
我們看到對(duì)于value變量而言,所有的賦值都是正確的,就會(huì)感覺是不是發(fā)現(xiàn)和any好像沒啥區(qū)別,真的是這樣嗎。當(dāng)我們給賦值其他類型時(shí),就會(huì)出現(xiàn)意想不到的問題,發(fā)現(xiàn)unknow類型只能被賦值給any類型和unknow類型本身,這就是跟any的區(qū)別。
- let value: unknown;
- let value1: unknown = value; // OK
- let value2: any = value; // OK
- let value3: boolean = value; // Error
- let value4: number = value; // Error
- let value5: string = value; // Error
- let value6: object = value; // Error
- let value7: any[] = value; // Error
- let value8: Function = value; // Error
所以得到:只有能夠保存任意類型值的容器才能保存 unknown類型的值。
值得注意的是,TS不允許我們對(duì)unknow類型的值執(zhí)行任何操作,必須得先執(zhí)行類型校驗(yàn)后來確定使用值的范圍。那么如何縮小unknow值的范圍呢?
很簡(jiǎn)單,有請(qǐng)我們的老朋友typeof、instanceof運(yùn)算符和自定義類型保護(hù)函數(shù),通過使用縮小類型范圍的技術(shù)都有助于 TypeScript 的基于控制流的類型分析。
例如,通過if語句分支
- function stringifyForLogging(value: unknown): string {
- if (typeof value === "function") {
- const functionName = value.name || "(anonymous)";
- return `[function ${functionName}]`;
- }
- if (value instanceof Date) {
- return value.toISOString();
- }
- return String(value);
- }
通過使用自定義類型保護(hù)函數(shù)縮小 unknown 類型范圍。
- function isNumberArray(value: unknown): value is number[] {
- return (
- Array.isArray(value) &&
- value.every(element => typeof element === "number")
- );
- }
- const unknownValue: unknown = [15, 23, 8, 4, 42, 16];
- if (isNumberArray(unknownValue)) {
- const max = Math.max(...unknownValue);
- console.log(max);
- }
盡管 unknownValue 已經(jīng)被歸為 unknown 類型,請(qǐng)注意它如何依然在 if分支下獲取到 number[] 類型。
參考文章
阿寶哥的《重學(xué)TS》
《ts中文文檔》
本文轉(zhuǎn)載自微信公眾號(hào)「前端萬有引力」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系前端萬有引力公眾號(hào)。