第一節(jié):TypeScript變量與數(shù)據(jù)類型

1. 變量的類型注釋

在JavaScript中, 變量的復(fù)制相對(duì)靈活, 除了const外, letvar聲明的變量可以賦予不同類型的數(shù)據(jù)

例如:

let val = 'string'
console.log(typeof val)
// 變量val的類型為string 類型

val = 10
console.log(typeof val)
// 變量val的類型為number 類型

val = true
console.log(typeof val)
// 變量val的類型為boolean 類型

示例中, 變量val可以賦值不同類型的變量, 而變量的類型取決于賦予變量的值.

如果我們需要限定變量的類型, 只允許給變量賦予某一種類型或幾種基本類型 的聯(lián)合類型, 我們就需要使用TypeScript給變量添加類型注釋

1.1 賦初值

基礎(chǔ)變量聲明的語(yǔ)法
let [變量]:[類型注釋] = 值

類型注釋需要用來(lái)描述變量可以被賦予那些類型的值.

// 1. 這樣會(huì)報(bào)錯(cuò),聲明的變量是number類型,卻被賦值為string類型的值
let a:number = 'hello'

// 2. 這樣也會(huì)報(bào)錯(cuò),聲明string類型后中途重新賦值了其他類型的值
let a:number = 20
a = 'hello'

這種方式實(shí)現(xiàn)的變量命名的好處,那就是在賦值的時(shí)候確定變量的類型,如果存值和聲明的變量類型不符合就會(huì)報(bào)錯(cuò)
聲明類型的變量,將只能賦予相同類型的值

如果聲明變量賦初始值,在大多數(shù)情況下,添加類型注釋并不是必須的, 原因在與TypeScript會(huì)根據(jù)我們賦予的初始值來(lái)自動(dòng)推斷變量的類型.

例如:

let a = 'hello'
// let a: string

a =  10
// 不能將類型“number”分配給類型“string”

TypeScript更加初始賦值'hello'推斷變量astring類型, 此時(shí)在將其他類型數(shù)據(jù)賦值給變量a就會(huì)報(bào)錯(cuò)

1.2 不賦初始值

語(yǔ)法
let [變量]:[類型注釋]

  1. 如果只創(chuàng)造了變量并規(guī)定類型,那么這個(gè)變量默認(rèn)值就是undefined
  2. 如果后面需要賦值時(shí),還是只能按照 聲明的變量類型來(lái)賦值,否則就會(huì)出錯(cuò)
let num:number;
console.log(num)  // undefined

num = 10  // ok

num = 'hello'
// 錯(cuò)誤:不能將類型“string”分配給類型“number”

聲明一個(gè)變量不管什么類型, 初始不賦值,變量默認(rèn)為undefined,這是遵循JavaScript的語(yǔ)言規(guī)范,

那么為什么undefined類型的值可以賦值給number類型的值呢? 那么先來(lái)了解一下TypeScript類型


2. 數(shù)據(jù)類型

TypeScript支持與JavaScript幾乎相同的數(shù)據(jù)類型阴绢,此外還提供了實(shí)用的枚舉類型方便我們使用霜第。

TypeScript 數(shù)據(jù)類型有:

  1. 數(shù)字類型 number
  2. 字符串類型 string
  3. 布爾類型 boolean
  4. undefined undefined
  5. null null
  6. 數(shù)組類型 []
  7. 元組 [] (數(shù)組的特殊形式)
  8. 對(duì)象類型 {}
  9. 函數(shù)類型 Function
  10. 任意類型 any
  11. void void
  12. never never
  13. unknown 不認(rèn)識(shí),代表 任何值,類似于any
  14. 枚舉 enum

2.1 字符串,數(shù)字,布爾類型

和JavaScript 字符串,數(shù)字,布爾類型一樣掐禁,并且所有數(shù)字都是浮點(diǎn)數(shù)。以及可以使用ES6字符串模板

// 字符串類型
let username = '張三'
let person :string = `字符串模板${username}`
console.log('person', person)

// 數(shù)字類型
let num: number = 30
console.log('num', num)

// 布爾類型
let bol: boolean = true;
console.log('bol',bol)


2.2 數(shù)組類型

JavaScript定義數(shù)組可以通過(guò)字面量和構(gòu)造函數(shù), TypeScript在添加數(shù)組的類型注釋也不同的方式

第一種就是使用字面量的方式

// 正確的寫(xiě)法
let arr: number[] = [10, 20, 30, 40];

let arr: string[] = ['a', 'b', 'c', 'd'];
// ...

// 錯(cuò)誤的寫(xiě)法
let arr:[number] = [10, 20, 30, 40];
// 這種寫(xiě)法指表示確定數(shù)組第一項(xiàng)的數(shù)據(jù)類型,其他的沒(méi)有確定,報(bào)錯(cuò)

number[]這種數(shù)組類型的定義方式, 其中[]表示是數(shù)組類型,number是基本數(shù)據(jù)類型, 表示數(shù)組每一項(xiàng)都是number類型

第二種:使用內(nèi)置的泛型Array

// 或者使用泛型
let arr: Array<number> = [10, 20, 30, 40];

let arr: Array<string> = ['a', 'b', 'c', 'd'];
// ...

上面的示例中數(shù)組內(nèi)所有的值都是同一種類型, 但在很多情況下數(shù)組內(nèi)會(huì)有不同數(shù)據(jù)類型的值,

那么就可以使用any類型或聯(lián)合類型

使用any類型定義數(shù)組內(nèi)的元素類型

let arr: any[]= [10, 'hello', true, null];
let arr: Array<any> = [10, 'hello', true, null];

// any表示任意類型,表示數(shù)組內(nèi)每一項(xiàng)都可以是任意類型

使用聯(lián)合類型數(shù)組, 聯(lián)合類型使用|符合,

聯(lián)合類型的前提是你明確的知道,數(shù)組內(nèi)只能存那些類型的數(shù)據(jù)

例如:我們希望一個(gè)數(shù)組只能存number,string兩種類型的值

let arr:(string | number)[] = ['hello' , 20, 'world']

let arr:Array<string | number> = ['hello' , 20, 'world']

(string | number)[]類型注釋中[]表示為數(shù)組類型,(string | number)就是聯(lián)合類型,表示數(shù)組沒(méi)一項(xiàng)可以是string類型或number類型.滿足一個(gè)即可


2.3 元組類型

元組類型其實(shí)就是另外一種Array數(shù)組 類型. 它確切的知道數(shù)組中包含多少元素, 以及它在特定位置包含哪些類型

元組類型表示一個(gè)已知元素?cái)?shù)量和每一項(xiàng)類型的數(shù)組,各元素的類型不必相同

其實(shí)元祖類型就是單獨(dú)定義數(shù)組的每一個(gè)數(shù)據(jù)的類型.

// 正確的寫(xiě)法
let arr:[number,string, boolean] = [10,'string',true]

// 錯(cuò)誤的寫(xiě)法
let arr:[string,string, boolean] = [10,'string',true]
// 編譯時(shí)報(bào)錯(cuò),Type 'number' is not assignable to type 'string'.
// 不能將數(shù)字類型的值賦值給字符串類型

// 注意定義數(shù)據(jù)類型和數(shù)據(jù)的數(shù)量保持一致, 數(shù)量不同則會(huì)報(bào)錯(cuò)
let arr:[string,string, boolean] = [10,'string']
// Property '2' is missing in type '[string, number]' but required in type '[string, number, boolean]'.

也可以先聲明元組類型的變量,之后再重新賦值

let a:[string,number,number,boolean,object]

// 這種 寫(xiě)法沒(méi)問(wèn)題
a =  ["hello",1,2,true,{age: 18}];

// 這種寫(xiě)法不行,上面創(chuàng)建變量時(shí),要求的類型和值的類型按照順序?qū)Σ簧?a = [1, "hello" , 2, true,{age: 18}];

// 這個(gè)寫(xiě)法也不可以,因?yàn)樯倭艘粋€(gè)對(duì)象
a = ["hello",1,2, true];

TypeScriptde的一個(gè)好處就是,會(huì)在代碼執(zhí)行前的類型檢查階段拋出錯(cuò)誤, 不想JavaScript只能在代碼運(yùn)行時(shí),才知道發(fā)生了什么錯(cuò)誤


2.4 object 引用數(shù)據(jù)類型

object是一個(gè)特殊的類型, 指定是任何不是原始值(string, number,bigint,boolean,symbol,null, undefined)的值.

這與空對(duì)象類型{}不同, 也與全局類型Object不同

object表示的是JavaScript中的引用類型,只要是具有屬性的類型都可以使用object類型

// 函數(shù)
const fn:object = () => console.log('fn')

// 數(shù)組
const arr:object = [10,20]

// 對(duì)象
const obj:object = {name:'hello', age:18}

因此這個(gè)類型在使用很少, 大多通過(guò)更詳細(xì)的類型添加類型注釋.

例如:

// 函數(shù)類型注釋
const fn:() => void = () => console.log('fn')

// 數(shù)組類型注釋
const arr:number[] = [10,20]

// 對(duì)象
const obj:{name:string,age:number} = {name:'hello', age:18}


2.5 對(duì)象類型

除了基本數(shù)據(jù)類型, 最常見(jiàn)的類型是對(duì)象類型. 對(duì)象類型是值任何帶有屬性的JavaScript值

對(duì)象類型幾乎是所有的屬性都要定義對(duì)象類型.

通過(guò)關(guān)鍵字object定義對(duì)象類型

// 對(duì)象類型
let ob:object =  { a: 10 }

這種類型注釋的對(duì)象并不限定屬性數(shù)量與屬性值的類型. 可以賦值任意類型

也可以通過(guò)字面量方式,列出所有屬性以及屬性類型來(lái)進(jìn)行類型注釋

let student:{name:string,age:number} = {name:'張三',age:18}


2.6 Function 類型

Function為全局類型, 描述JavaScript中所有函數(shù)值的屬性, Function類型總是可以調(diào)用類型值的特殊屬性, 這些調(diào)用返回any, 一般也不常用

function example(fn:Function){
    return fn(1,2)
}

參數(shù)fn是一個(gè)具有函數(shù)屬性的函數(shù)類型, fn()的調(diào)用是一個(gè)無(wú)類型的函數(shù)調(diào)用, 因?yàn)榉祷仡愋蜑?code>any類型不太安全.最好避免使用,.

可以使用更加詳細(xì)的函數(shù)類型注釋

例如:

function example(fn:() => void){
    return fn(1,2)
}


2.7 任意類型 any

TypeScript也有一個(gè)特殊的類型: any類型,當(dāng)你不希望某個(gè)特定的值導(dǎo)致類型檢查錯(cuò)誤時(shí),可以使用它

通常當(dāng)你聲明一個(gè)變量, 沒(méi)有確定初始類型,也沒(méi)有賦初始值是,或者賦初值為undefined或null時(shí), 變量的類型默認(rèn)為any類型.

也就是說(shuō):當(dāng)您不指定類型,并且 TypeScript 無(wú)法從上下文中推斷出它時(shí),編譯器通常會(huì)默認(rèn)為any.

any類型的變量賦值任何類型的數(shù)據(jù)都不會(huì)報(bào)錯(cuò)

let a = null
// 或者
let a = undefined
// 或者
let a;
// let a: any

a = 'aa'
console.log(a) // 'aa'
a = 30
console.log(a) // 30

一般來(lái)說(shuō)并不建議大量使用any類型.當(dāng)你明確知道一個(gè)變量之后不會(huì)被賦予其他類型的數(shù)據(jù), 那么就可以在聲明變量時(shí)添加詳細(xì)的類型注釋;

只有當(dāng)你在不確定變量未來(lái)會(huì)賦予什么樣類型的值時(shí), 可以嘗試使用

注意:

any類型的變量會(huì)跳過(guò)類型檢查

例如:

let obj: any = { x: 0 };

// 下面代碼將沒(méi)有一行代碼編譯錯(cuò)誤
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;

實(shí)例中變量objany類型, 因此obj身上的所有操作都會(huì)跳過(guò)類型檢查, 因此在TypeScript編譯代碼時(shí)不會(huì)報(bào)錯(cuò).

但是執(zhí)行編譯后的代碼可能會(huì)出錯(cuò).

2.8 空類型 void undefined null

Void 表示沒(méi)有任何類型 空
通常聲明一個(gè)Void 類型沒(méi)什么意義,因?yàn)檫@個(gè)類型的變量只能賦值為undefined和null

let a: void = undefined;
console.log(a)

let a: void = null;
console.log(a)

// 賦值其他類型的值就會(huì)報(bào)錯(cuò)
let a: void = 123;
console.log(a)
// 報(bào)錯(cuò):不能將類型“number”分配給類型“void”

在TypeScript里,undefined和null 兩者各自都有自己類型分別叫做undefined和null;和void相似,他們的類型本身用處不大:

// 聲明一個(gè)undefined類型變量
let und: undefined;
und = undefined;
und = null;
console.log(und)

// 聲明一個(gè)null類型的變量
let nul: null
nul = null;
und = undefined;
console.log(nul)

void一樣, undefinednull類型只能賦值undefinednull值, 本身意義不大

默認(rèn)情況下,null和undefined 是 所有類型的子類型
就是說(shuō)你可以把null和undefined賦值給其他類型的變量

let num:number = undefined;
let num:number = null;
let str:string = undefined;
// ....

但是,不能將其他類型的值賦值給void,undefined,null類型的變量

let un:undefined =  12;
let aa:null = 'aa';
let bb:void = true;

這樣寫(xiě)會(huì)報(bào)錯(cuò)

2.9 never類型

never類型表示的是那些永不存在的值的類型
這個(gè)嚴(yán)格來(lái)說(shuō)算不上新的數(shù)據(jù)類型,只是開(kāi)發(fā)者對(duì)于一些值所起的作用的判斷而已

比如:

  1. 總是會(huì)拋出異常,throw錯(cuò)誤或是返回一個(gè)error類型的數(shù)據(jù)
  2. 根本就不會(huì)有返回值的函數(shù)表達(dá)式(死循環(huán)函數(shù))
// 沒(méi)有返回值
function error(msg:string):never {
  throw new Error(msg)
}

// 一旦有了返回值never類型就報(bào)錯(cuò)
function error():never {
  retrun new Error('something failed')
}
// 報(bào)錯(cuò): 不能將類型“Error”分配給類型“never”。

// 哪怕沒(méi)有顯示的return 也會(huì)報(bào)錯(cuò), 因?yàn)楹瘮?shù)有默認(rèn)返回undefined
function error():never {
  new Error('something failed')
}
// 返回“never”的函數(shù)不能具有可訪問(wèn)的終結(jié)點(diǎn)疆拘。


// 死循環(huán)函數(shù)
function infiniteLoop():never{
  while(true){
    console.log('帥")
  }
}

never類型是任何類型的子類型,任何其他類型的值都不能賦值給never類型.即使any也不可以

let n:never;
n = 12
// 不能將類型“number”分配給類型“never”


2.10 unknown 類型

unknown類型代表任何值, 這類似于any類型, 但更安全, 因?yàn)橛弥底鋈魏问虑槎际遣缓戏ǖ?/p>

例如:

function fn1(a:any){
    // 調(diào)用any類型的屬性是合法的
    // 任意類型有可能是對(duì)象類型
    a.b()
}


function fn2(a:unknown){
    // unknown 未知類型, 不確定它是什么值
    a.b()
    // 報(bào)錯(cuò):類型“unknown”上不存在屬性“b”。
}


2.11 枚舉類型

枚舉類型是TypeScript添加到JavaScript的一項(xiàng)功能, 它允許描述一個(gè)值, 該值可能是一組可能的命名常量之一.

與大多數(shù)TypeScript功能不同,這不是對(duì)JavaScript的類型級(jí)添加, 而是添加到語(yǔ)言和運(yùn)行時(shí)的東西.

詳細(xì)內(nèi)容稍后章節(jié)介紹

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寂曹,一起剝皮案震驚了整個(gè)濱河市入问,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌稀颁,老刑警劉巖锅尘,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件威鹿,死亡現(xiàn)場(chǎng)離奇詭異彭则,居然都是意外死亡哎媚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門阶女,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)颊糜,“玉大人,你說(shuō)我怎么就攤上這事秃踩〕挠悖” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵憔杨,是天一觀的道長(zhǎng)鸟赫。 經(jīng)常有香客問(wèn)我,道長(zhǎng)消别,這世上最難降的妖魔是什么抛蚤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮寻狂,結(jié)果婚禮上岁经,老公的妹妹穿的比我還像新娘。我一直安慰自己蛇券,他們只是感情好缀壤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著纠亚,像睡著了一般塘慕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上菜枷,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天苍糠,我揣著相機(jī)與錄音叁丧,去河邊找鬼啤誊。 笑死岳瞭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚊锹。 我是一名探鬼主播瞳筏,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼牡昆!你這毒婦竟也來(lái)了姚炕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丢烘,失蹤者是張志新(化名)和其女友劉穎柱宦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體播瞳,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掸刊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赢乓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忧侧。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖牌芋,靈堂內(nèi)的尸體忽然破棺而出蚓炬,到底是詐尸還是另有隱情,我是刑警寧澤躺屁,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布肯夏,位于F島的核電站,受9級(jí)特大地震影響犀暑,放射性物質(zhì)發(fā)生泄漏熄捍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一母怜、第九天 我趴在偏房一處隱蔽的房頂上張望余耽。 院中可真熱鬧,春花似錦苹熏、人聲如沸碟贾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)袱耽。三九已至,卻和暖如春干发,著一層夾襖步出監(jiān)牢的瞬間朱巨,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工枉长, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冀续,地道東北人琼讽。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洪唐,于是被迫代替她去往敵國(guó)和親钻蹬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容