第四節(jié):TypeScript 數(shù)組類型

數(shù)組類型

1. 數(shù)組類型聲明

在前面數(shù)據(jù)類型已經(jīng)了解過,聲明數(shù)組類的方式有兩中, 一種字面量方式, 一種泛型方式(很像JavaScript構(gòu)造函數(shù))

例如:

// 字面量方式聲明數(shù)組
let myArr: string[] = ['hello', 'world']
let myArr2: number[] = [20,30]

// 內(nèi)置泛型方式
// 注釋Array<> 使用的是泛型的<>  不是構(gòu)造函數(shù)的()
let myArr3: Array<string> = ['hello', 'world']
let myArr4: Array<number> = [20,30]

還需要注意是字面量方式聲明數(shù)組類型, 類型不能寫在[]內(nèi)部, 寫在內(nèi)部就變成元組類型

其實兩種聲明數(shù)組類型的方式本質(zhì)是 同一個

type[]聲明的數(shù)組類型 只是Array<type>聲明數(shù)組類型的簡寫方式

Array就很像上一節(jié)中通用類型中的Box, 所以Array本質(zhì)就是一個內(nèi)置的泛型類型


2. readonlyArray 只讀數(shù)組類型

TypeScript 除了Array<T>類型 還具有一個ReadonlyArray<T>類型,

ReadonlyArray類型和Array 類型很相似,但它是一個特殊的類型,用于描述不應(yīng)該更改的數(shù)組


2.1 Array<T>聲明數(shù)組

通過Array<T>聲明的數(shù)組是可以修改的

let arr:string[] = ['無人機(jī)', '車輛','巡邏車']
let device: Array<string> = arr
console.log('device', device)  // ['無人機(jī)', '車輛','巡邏車']

// 修改數(shù)組項
device[0] = '自行車'

console.log('device', device) //  ["自行車", "車輛", "巡邏車"]
console.log(arr === device)  // true


2.2 ReadonlyArray<T>聲明數(shù)組

通過ReadonlyArray<T>聲明的數(shù)組不能被修改

let arr:string[] = ['無人機(jī)', '車輛','巡邏車']
let device: ReadonlyArray<string> = arr

device[0] = '自行車'  // error
// 類型“readonly string[]”中的索引簽名僅允許讀取


device.push('aa')    // error
// 但是ReadonlyArray 類型的數(shù)組在新增時報錯
// 類型“readonly string[]”上不存在屬性“push”, 也及時沒有push方法耻讽。

很像對象的readonly修飾符,它主要的作用就是提醒工具, 即當(dāng)我們看到一個通過ReadonlyArray類型注釋的變量時,其實就是告知我們,這個數(shù)組不可修改


注意, 與Array類型不同, ReadonlyArray只作為類型使用, 不能當(dāng)成構(gòu)造函數(shù)使用

// 報錯: ReadonlyArray 僅表示類型, 但是這里作為值使用
new ReadonlyArray('hello','world')

Array不僅僅是TypeScript中的類型, 還是JavaScript中的構(gòu)造函數(shù)

// ok
new Array('hello','world')


相反,我們可以將常規(guī)的Array類型數(shù)組分配給ReadonlyArray

const roArray:ReadonlyArray<string> = ['red','green','blue']


2.3 ReadonlyArray<T>簡寫方式

正如TypeScript為Array<Type>提供了簡寫方式Type[]

TypeScript也為ReadonlyArray<Type>提供了簡寫方式,寫法為readonly Type[]

例如:

let device: ReadonlyArray<string> = ['無人機(jī)', '車輛','巡邏車']

// 可以簡寫為
let device2: readonly string[] = ['無人機(jī)', '車輛','巡邏車']


3. 與對象readonly屬性的不同

需要注意的是, 與readonly屬性修飾符不同, 常規(guī)的Array類型和ReadonlyArray類型之間賦值是相反的


3.1 對象只讀屬性賦值
// 只讀屬性接口
interface RoName{
    readonly name:string
}
// 常規(guī)屬性接口
interface Name{
    name:string
}

// 聲明變量
let roName: RoName = {
    name: '張三'
}
let uname: Name = {
    name:'李四'
}

// 1. 將readonly name屬性值賦值給常規(guī)name屬性值, 完全ok
uname.name = roName.name

// 2. 將常規(guī)name屬性賦值給readonly name 屬性報錯
// 報錯: 無法分配name ,因為它是只讀屬性
roName.name = uname.name


3.2 只讀數(shù)組賦值

ArrayReadonlyArray之間的賦值與常規(guī)屬性和readonly 屬性相互賦值完全相反

let x:readonly string[]  = ['hello']
let y:string[]  = ['world']

// 1. 可以將常規(guī)Array類型值賦值給ReadonlyArray 類型
x = y;
console.log('x',x)
// x ['world']

// 2.不能將ReadonlyArray類型分配給Array類型
y = x;
// 報錯:類型readonly string[]為只讀類型,不可分配給可變類型 string[]

總結(jié):

  1. 對象的普通屬性不可賦值給readonly只讀屬性
  2. 數(shù)組readonly只讀數(shù)組 不可賦值給常規(guī)數(shù)組


4. 元組類型

4.1 元組類型

元組類型是另外一種Array類型, 它確切的知道自己包含多少元素,多少類型, 以及每一個元素類型和位置

// 類型別名定義元組類型
type StringNumberArray =  [string,number]

這里 StringNumberArray就是由stringnumber組成 的元組類型,

就像ReadonlyArray在運(yùn)行時沒有表示, 但對TypeScript來說很重要,

對于類型系統(tǒng),元組類型是描述索引以及索引包含的類型所形成的數(shù)組,

示例中:

// 類型別名定義元組類型
type StringNumberArray =  [string,number]

// 使用類型注釋
let arr:StringNumberArray;

let a = arr[0]
// let a: string

let b = arr[1]
// let b: number

根據(jù)元組類型索引0對應(yīng)的值類型為string, 索引1對應(yīng)的值類型為number類型


我們除了可以通過索引單個取值,還可以使用JavaScript的數(shù)組解構(gòu)來解構(gòu)元組

// 類型別名定義元組類型
type StringNumberArray =  [string,number]

// 使用類型注釋
let arr:StringNumberArray;

let [a,b]= arr;

console.log(a)
// let a: string

console.log(b)
// let b: number

元組類型在大量基于約定 的API中很好用, 因為每個元素的含義都是顯而易見, 這就是的我們在解構(gòu)變量中可以靈活的命名變量


4.2 操作超過元組索引賦值

如果我們此時試圖獲取超過元組數(shù)量對應(yīng)的索引位置值時,會得到一個錯誤

// 類型別名定義元組類型
type StringNumberArray =  [string,number]

// 使用類型注釋
let arr:StringNumberArray;

let c = arr[2]
// 長度為 "2" 的元組類型 "StringNumberArray" 在索引 "2" 處沒有元素

報錯:告訴我們,我們想獲取索引對于的值在元組類型上沒有元素


如果我們嘗試在超過元素數(shù)組對應(yīng)的索引位置賦值時,也會有相同錯誤

// 類型別名定義元組類型
type StringNumberArray =  [string,number]

// 使用類型注釋
let arr:StringNumberArray;

arr[2] = 'hello'
// 長度為 "2" 的元組類型 "StringNumberArray" 在索引 "2" 處沒有元素官脓。


4.3 特殊的Array類型

除了那些長度檢查之外, 像這樣簡單的元組類型等價于Array為特定索引聲明屬性類型的版本, 同時length屬性使用明確的數(shù)字文字類型聲明

// 元組類型
type StringNumberArray = [string, number] 

// 特殊的Array類型
interface StringNumberObj {
    length: 2
    0: string
    1: number
}


4.4 元組的可選屬性

元組元素可以通過在元素類型后面添加?來表示可選屬性, 可選的元組元素只能出現(xiàn)在元組的末尾, 也同樣會影響length

// 可選元組類型
type OptionalTuple = [number,number, number?]

// 可選元組中可選元素可以選擇是否賦值
let arr:OptionalTuple = [10,20]

let arr2:OptionalTuple = [10,20,30]

// 解構(gòu)元組類型注釋的變量
const [x,y,z] = arr

console.log(x)
// const x: number

console.log(y)
// const y: number

console.log(z)
// const z: number | undefined

console.log(arr.length)
// (property) length: 2 | 3

示例中,固定的元素有固定的類型, 可選元素是聯(lián)合類型, 沒有值時為undefined,

元組的長度也是23, 不是一個確定的長度


4.5 元組的剩余運(yùn)算符

元組也可以有剩余元素, 他們必須是數(shù)組/元組類型

type StringNumberBooleans = [string, number, ...boolean[]];
type StringBooleansNumber = [string, ...boolean[], number];
type BooleansStringNumber = [...boolean[], string, number];

說明:

  1. StringNumberBooleans元組,其前兩個元素分別是stringnumber,但后面可以有任意數(shù)量的boolean
  2. StringBooleansNumber元組陈哑,第一個元素是string搜吧,中間任意數(shù)量的boolean類型,但結(jié)尾必須是number類型
  3. BooleansStringNumber元組,起始元素是任意數(shù)量的boolean類型,但結(jié)尾必須是stringnumber`類型坦胶。

注意,帶有剩余運(yùn)算符元素的元組沒有固定的長度, 它只有一組位于不同位置的知名元素

const a: StringNumberBooleans = ["hello", 1];
const b: StringNumberBooleans = ["beautiful", 2, true];
const c: StringNumberBooleans = ["world", 3, true, false, true, false, true];

剩余運(yùn)算符元素是任意個,當(dāng)然也包含0個, 因此類型中boolean類型的值可以沒有


4.6 元組的可選屬性與剩余元素的使用

TypeScript允許將元組和參數(shù)列表對應(yīng)起來,

function example(...args:[string,number,...boolean[]]){
    const [name,version,input] = args
    console.log('args',args)
    // parameter) args: [string, number, ...boolean[]]
}

example('hello',10,true)

因為...arg會將函數(shù)參數(shù)收集成為數(shù)組, 但這個數(shù)組必須符合元組類型

也就是說這個函數(shù)必須傳遞兩個參數(shù), 第一個為字符串類型,第二個為數(shù)字類型, 其余可以為任意多的布爾類型

其實示例中函數(shù)的寫法等價于如下寫法

function example(name:string,version:number,...input:boolean[]){
    //...
}

當(dāng)你 想用給一個剩余參數(shù)獲取可變數(shù)量參數(shù)時, 這很方便


4.7 readonly 元組類型

元組類型也有readonly只讀類型, 可以通過在元組前面添加readonly修飾符來指定, 就像數(shù)組簡寫語法一樣

// 只讀元組類型
let arr: readonly [string,number] = ['hello', 20]

// 修改只讀元組類型
arr[0] = 'world'
// 無法分配到 "0" 透典,因為它是只讀屬性

在大多數(shù)代碼中, 元組往往被創(chuàng)建后并未修改, 此時元組類型注釋可以將readonly 作為很好的默認(rèn)設(shè)置


4.8 斷言數(shù)組變?yōu)樵M類型

使用as const斷言的數(shù)組,TypeScript會將其推斷為readonly 元組類型

例如:

// TypeScript 將會推斷為普通數(shù)組類型  number[]
let arr = [3,4] 
// let arr: number[]

//  正常賦值
arr[0] = 20

沒有類型注釋的數(shù)組會被TypeScript推斷為數(shù)組類型.

此時可以使用斷言, 將普通數(shù)組斷言為元組類型

// 使用斷言為const TypeScript將會推斷為readonly [3,4]元組類型
let arr = [3,4] as const
// let arr: readonly [3, 4]

//  readonly 元組賦值報錯
arr[0] = 10
// 無法分配到 "0" ,因為它是只讀屬性
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顿苇,一起剝皮案震驚了整個濱河市峭咒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纪岁,老刑警劉巖凑队,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異幔翰,居然都是意外死亡漩氨,警方通過查閱死者的電腦和手機(jī)西壮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叫惊,“玉大人款青,你說我怎么就攤上這事』粽” “怎么了抡草?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蔗坯。 經(jīng)常有香客問我渠牲,道長,這世上最難降的妖魔是什么步悠? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任签杈,我火速辦了婚禮,結(jié)果婚禮上鼎兽,老公的妹妹穿的比我還像新娘答姥。我一直安慰自己,他們只是感情好谚咬,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布鹦付。 她就那樣靜靜地躺著,像睡著了一般择卦。 火紅的嫁衣襯著肌膚如雪敲长。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天秉继,我揣著相機(jī)與錄音祈噪,去河邊找鬼。 笑死尚辑,一個胖子當(dāng)著我的面吹牛辑鲤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杠茬,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼月褥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瓢喉?” 一聲冷哼從身側(cè)響起宁赤,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎栓票,沒想到半個月后决左,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年哆窿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厉斟。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡挚躯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出擦秽,到底是詐尸還是另有隱情码荔,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布感挥,位于F島的核電站缩搅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏触幼。R本人自食惡果不足惜硼瓣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望置谦。 院中可真熱鬧堂鲤,春花似錦、人聲如沸媒峡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谅阿。三九已至半哟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間签餐,已是汗流浹背寓涨。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氯檐,地道東北人缅茉。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像男摧,于是被迫代替她去往敵國和親蔬墩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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