遨游TypeScript海洋之定義變量和數(shù)據(jù)類型

變量和數(shù)據(jù)類型

熟悉JavaScript的小伙伴都知道,typescript是JavaScript的超集,也就是說它包含JavaScript。所以我覺得,只要你想擁有更佳的模塊管理,讓你的開發(fā)更佳嚴(yán)謹(jǐn),那一定要學(xué)習(xí)使用typescript,今天我們接著來了解如何在TypeScript中定義變量,并熟悉JavaScript類型在TypeScript中的變化和TypeScript中新增的類型。

一. 變量聲明方式

1.1. 聲明變量的格式

我們已經(jīng)強調(diào)過很多次,在TypeScript中定義變量需要指定 標(biāo)識符 的類型。

所以完整的聲明格式如下:

var/let/const 標(biāo)識符: 數(shù)據(jù)類型 = 賦值;

比如我們聲明一個message,完整的寫法如下:

注意:這里的string是小寫的,和String是有區(qū)別的

string是TypeScript中定義的字符串類型,String是ECMAScript中定義的一個類

let message: string = "Hello World";

message = "Hello TypeScript"; // 正確的做法

message = 20; // 錯誤的做法,因為message是一個string類型

1.2. 聲明變量的關(guān)鍵字

在TypeScript定義變量(標(biāo)識符)和ES6之后一致,可以使用var、let、const來定義:

var myname: string = "abc";

let myage: number = 20;

const myheight: number = 1.88;

但是,我們會發(fā)現(xiàn)使用var關(guān)鍵字會有一個警告:

? ? ? var關(guān)鍵字警告

可見,在TypeScript中并不建議再使用var關(guān)鍵字了,主要原因和ES6升級后let和var的區(qū)別是一樣的,var是沒有塊級作用域的,會引起很多的問題,這里不再展開探討。

所以,在之后的開發(fā)中,我們定義變量主要使用let和const

1.3. 變量的類型推斷

在開發(fā)中,有時候為了方便起見我們并不會在聲明每一個變量時都寫上對應(yīng)的數(shù)據(jù)類型,我們更希望可以通過TypeScript本身的特性幫助我們推斷出對應(yīng)的變量類型:

let message = "Hello World";

上面的代碼我們并沒有指定類型,但是message實際上依然是一個字符串類型:

給message賦值一個number

這是因為在一個變量第一次賦值時,會根據(jù)后面的賦值內(nèi)容的類型,來推斷出變量的類型:

上面的message就是因為后面賦值的是一個string類型,所以message雖然沒有明確的說明,但是依然是一個string類型

let message = "Hello World"; // string類型

let age = 20; // number類型

let isFlag = true; // boolean類型

1.4. 聲明name報錯

我們在TypeScript的文件中聲明一個name(很多其他的名字也會)時,會報錯:

聲明name報錯信息

主要錯誤信息:

無法重新聲明塊范圍變量“name”

我們前面明明(明明說管我什么事)沒有聲明name,但是卻說我們重復(fù)聲明了

這次是因為我們的typescript 將 DOM typings 作為全局的運行環(huán)境;

所以當(dāng)我們聲明 name時, 與 DOM 中的全局? name 屬性出現(xiàn)了重名;

name的聲明位置

如何解決這個問題呢?

有兩種方案:去掉 DOM typings 的環(huán)境和聲明模塊

方式一:刪除DOM typings的環(huán)境

但是這種辦法對于我們來說并不合適,因為我們依然希望在DOM下編譯我們的TypeScript代碼

刪除DOM typing

方式二:聲明我們的ts文件為一個模塊

既然與全局的變量出現(xiàn)重名,那我們將腳本封裝到模塊(module)中,因為模塊有屬于自己的作用域,就不會和全局的產(chǎn)生沖突:

在 Typescript 中,我們可以使用ES6的export來導(dǎo)出一個對象,并且該文件被視為 module

let name = "coderwhy";

export {};

1.5. console.log報錯

另外為了測試方便我們經(jīng)常使用console.log來進行測試,但是使用時會報一個警告:

console.log警告

這個時候,我們可以配置

配置tslint

"no-console": false

二. JavaScript數(shù)據(jù)類型

2.1. number類型

數(shù)字類型是我們開發(fā)中經(jīng)常使用的類型,TypeScript和JavaScript一樣,不區(qū)分整數(shù)類型(int)和浮點型(double),統(tǒng)一為number類型。

// 1.數(shù)字類型基本定義

let num = 100;

num = 20;

num = 6.66;

如果你學(xué)習(xí)過ES6應(yīng)該知道,ES6新增了二進制和八進制的表示方法,而TypeScript也是支持二進制、八進制、十六進制的表示:

// 2.其他進制表示

num = 100; // 十進制

num = 0b110; // 二進制

num = 0o555; // 八進制

num = 0xf23; // 十六進制

2.2. boolean類型

boolean類型只有兩個取值:true和false,非常簡單

// boolean類型的表示

let flag: boolean = true;

flag = false;

flag = 20 > 30;

2.3. string類型

string類型是字符串類型,可以使用單引號或者雙引號表示:

注意:如果打開了TSLint,默認(rèn)情況下推薦使用使用雙引號

// string類型表示

let message: string = "Hello World";

message = 'Hello TypeScript';

同時也支持ES6的模板字符串來拼接變量和字符串:

const name = "why";

const age = 18;

const height = 1.88;

const info = `my name is ${name}, age is ${age}, height is ${height}`;

console.log(info);

2.4. array類型

數(shù)組類型的定義也非常簡單,有兩種方式:

但是TSLint會推薦我們使用上面這種方式

const names1: string[] = ["why", "abc", "cba"];

const names2: Array<string> = ["why", "abc", "cba"];

2.5. object類型

object對象類型可以用于描述一個對象:

// object類型表示

const myinfo: object = {

? name: "why",

? age: 20,

? height: 1.88,

};

但是上面的代碼會報一個警告:

object定義后警告

這是因為TSLint建議我們所有的key按照字母進行排序,但是這個并不是特別有必要,我們還是可以關(guān)閉掉:

關(guān)閉TSLint字母排序

"object-literal-sort-keys": false

屬性是不可以訪問的

如果我們訪問myinfo中的屬性,會發(fā)現(xiàn)報錯:

找不到name屬性

這是因為TypeScript并不知道某一個object類型上面就有一個name的屬性。

但是如果我們讓它是類型推斷的,就可以正常的訪問:

這是因為推導(dǎo)出來的類型,是如下的類型

myinfo的類型

還有一種方法是定義后面會學(xué)到的接口,TypeScript一個非常好用的特性就是接口interface,后續(xù)我們會進行非常詳細(xì)的學(xué)習(xí)

2.6. symbol類型

在ES5中,如果我們是不可以在對象中添加相同的屬性名稱的,比如下面的做法:

const person = {

? identity: "程序員",

? identity: "老師",

}

通常我們的做法是定義兩個不同的屬性名字:比如identity1和identity2。

但是我們也可以通過symbol來定義相同的名稱,因為Symbol函數(shù)返回的是不同的值:

const s1 = Symbol("identity");

const s2 = Symbol("identity");

const person = {

? [s1]: "程序員",

? [s2]: "老師",

};

這是Symbol的一個用法,更多其他用法大家可以自行學(xué)習(xí),或者等到后續(xù)確實需要用到時,我們再詳細(xì)講解。

2.7. null和undefined

在 JavaScript 中,undefined 和 null 是兩個基本數(shù)據(jù)類型。

在TypeScript中,它們各自的類型也是undefined和null,也就意味著它們既是實際的值,也是自己的類型:

const n: null = null;

const u: undefined = undefined;

三. TypeScript數(shù)據(jù)類型

?TypeScript在原有的JavaScript基礎(chǔ)上引入了很多好用的類型:enum枚舉類型、tuple元組類型、any類型、void類型、never類型等”

3.1. enum類型

3.1.1. 枚舉的基本定義

枚舉類型在很多語言都有的類型,比如C++、Java等等,并且也非常好用,所以TypeScript引入了enum類型,讓我們開發(fā)更好的方便和安全。

枚舉類型通常是定義一組數(shù)據(jù):

enum Direction {

? EAST,

? WEST,

? NORTH,

? SOUTH,

}

const d1 = Direction.EAST;

const d2 = Direction.NORTH;

3.1.2. 枚舉類型的值

枚舉類型有自己的值,比如打印上面的d1和d2

打印d1和d2結(jié)果

默認(rèn)情況下,枚舉中的數(shù)據(jù)是從0開始的,我們可以改變它的初始化值,比如下面的代碼:

enum Direction {

? EAST = 10,

? WEST,

? NORTH,

? SOUTH,

}

const d1 = Direction.EAST;

const d2 = Direction.NORTH;

console.log(d1); // 10

console.log(d2); // 12

也可以全部自己來指定:

enum Direction {

? EAST = 10,

? WEST = 20,

? NORTH = 30,

? SOUTH = 40,

}

const d1 = Direction.EAST;

const d2 = Direction.NORTH;

console.log(d1); // 10

console.log(d2); // 30

我們也可以通過對應(yīng)的值去獲取對應(yīng)的數(shù)據(jù)名稱:

console.log(Direction[10]); // EAST

console.log(Direction[30]); // NORTH

3.2. tuple類型

3.2.1. tuple的基本使用

tuple是元組類型,很多語言中也有這種數(shù)據(jù)類型,比如Python、Swift等。

const tInfo: [string, number, number] = ["why", 18, 1.88];

const item1 = tInfo[0]; // why, 并且知道類型是string類型

const item2 = tInfo[1]; // 18, 并且知道類型是number類型

3.2.1. tuple和數(shù)組類比

初學(xué)tuple會覺得它和數(shù)組非常相似

但是數(shù)組中通常會定義一組相同的數(shù)據(jù),如果數(shù)據(jù)不同會造成類型的丟失:

注意:這里我使用了一種聯(lián)合類型,后面會講到

const aInfo: Array<string|number> = ["why", 18, 1.88];

const itema = aInfo[0]; // why,但是并不知道itema是string類型還是number類型

3.3. any類型

在某些情況下,我們確實無法確定一個變量的類型,并且可能它會發(fā)生一些變化,這個時候我們可以使用any類型(類似于Dart語言中的dynamic類型)

let a: any = "why";

a = 123;

a = true;

const aArray: any[] = ["why", 18, 1.88];

3.4. void類型

void類型通常用于函數(shù)沒有返回值時來使用:

首先我們需要說明的是,在TypeScript中函數(shù)也是有類型的

下面的函數(shù),雖然我們沒有指定它的類型,但是它會通過類型推導(dǎo)出來:

const sum = (num1: number, num2: number) => {

? return num1 + num2;

};

// 相當(dāng)于下面的寫法

const sum: (num1: number, num2: number) => number = (num1: number, num2: number) => {

? return num1 + num2;

};

sum函數(shù)的類型

如果一個函數(shù)沒有返回值,那么它的返回值類型就是void

我們可以將null和undefined賦值給void類型,也就是函數(shù)可以返回null或者undefined

const sayHello: (name: string) => void = (name: string) => {

? console.log("hello " + name);

};

3.5. never類型

never類型表示一種從來不會存在的值的類型,有點繞,我們來這樣理解:

如果一個函數(shù)中是一個死循環(huán),那么這個函數(shù)會返回東西嗎?不會,那么寫void類型或者其他類型作為返回值類型都不合適,我們就可以使用never類型。

如果一個函數(shù)是拋出一個異常,那么這個函數(shù)是不是也沒有返回值呢?這個時候我們也可以使用never類型。

死循環(huán)的函數(shù)

拋出異常的函數(shù)

?備注:所有內(nèi)容首發(fā)于公眾號Flutter、TypeScript、React、Node、uniapp、小程序開發(fā)、數(shù)據(jù)結(jié)構(gòu)與算法等等,也會更新一些自己的學(xué)習(xí)心得等,歡迎大家關(guān)注。

看到這里,想必你已經(jīng)了解關(guān)于typescript定義變量和數(shù)據(jù)類型的變化相關(guān)的信息,但其實這只是typescript中的冰山一角。其中還有更多的奧秘等待我們發(fā)現(xiàn)。我也會接著為你慢慢揭開它的神秘面紗。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容