TypeScript - 陣列的型別
在 TypeScript 中,可以使用多種方式來定義陣列的型別。
使用型別後綴法 Type Suffix Syntax:「型別 + 方括號」
在變數名稱後面加上 []
,表示這個變數是一個陣列,裡面包含的元素都是同一個型別。
let numbers: number[] = [1, 2, 3, 4, 5]
let names: string[] = ['Anna', 'Bob', 'Cathy']
使用陣列泛型 Array Generic
我們也可以使用陣列泛型(Array Generic) Array<ElementType>
來表示陣列,其中 ElementType
是你想要的陣列元素型別。:
let numbers: Array<number> = [1, 2, 3, 4, 5]
let names: Array<string> = ['Anna', 'Bob', 'Cathy']
泛型(Generics)是指在定義函式、介面或類別的時候,不預先指定具體的型別,而在使用的時候再指定型別的一種特性。
泛型允許你在多個型別之間共享相同的結構,使得程式碼更具可複用性。
在這種表示法中,我們可以將其他型別放入尖括號 <>
中,例如基本型別、自定義型別或介面。
對陣列中的元素進行型別檢查
如果嘗試將不符合指定型別的值添加到陣列中,可以看到 TypeScript 會報錯:
let numbers: number[] = [1, 2, 3, 4, 5]
numbers.push('6')
// index.ts:2:14 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
使用介面表示陣列
interface NumberArray {
[index: number]: number;
}
let numbers: NumberArray = [1, 2, 3, 4, 5]
在這個例子中,我們定義了一個 NumberArray
介面,它表示只要索引(index)的型別是 number 時,那麼值的型別就必須是 number
。
雖然介面也可以用來表示陣列,但通常我們會直接採用更簡單的「型別+括號」方式來表示陣列:
let numbers: number[] = [1, 2, 3, 4, 5]
那什麼時候才會用到介面來表示陣列呢?
當我們需要描述具有多個屬性和方法的複雜數據結構時,用介面來表示陣列反而會讓數據組織和結構更清晰易讀。
比方說,我們常用它來表示「類陣列物件」。
類陣列物件 Array-like Object
「類陣列物件」並不是陣列型別,而是指具有某些類似陣列特性的物件。它可以向陣列一樣使用索引存取元素,並且具有 length 屬性。
類陣列物件:arguments
比如在 Javascript 中, arguments
是一個類陣列物件,因此不能使用一般的陣列方式來描述,需使用介面來描述:
// 使用型別+方括號表示 --> 報錯
function sum() {
let args: number[] = arguments;
}
// Type 'IArguments' is missing the following properties from type 'number[]': pop, push, concat, join, and 24 more.
// 使用介面表示 --> 正確
function sum() {
let args: {
[index: number]: number;
length: number;
callee: Function;
} = arguments;
}
內建介面 - IArguments
IArguments
是 TypeScript 的內建介面,已經定義好了型別,用於描述類陣列物件(Array-like Object),特別是用於描述 JavaScript 函數中的 arguments
類陣列物件。
它實際上就是:
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
caller: Function;
}
IArguments
介面約束了:
索引的型別是數字時,值的型別是
any
需有
length
、callee
、caller
屬性
其他常見的類陣列物件
除了 IArguments
之外其他常見的類陣列物件也有對應的介面:
1. NodeList
使用 document.querySelectorAll
或其他類似方法選取 DOM 元素時,會返回一個 NodeList
類陣列物件。它表示一組節點(Node)。
const nodeList = document.querySelectorAll("div");
2. HTMLCollection
使用 document.getElementsByClassName
、document.getElementsByTagName
等方法選取 DOM 元素時,會返回一個 HTMLCollection
類陣列物件。它表示一組 HTML 元素。
const htmlCollection = document.getElementsByClassName("some-class");
類陣列物件都的共同特點
具有數字索引
具有
length
屬性可以像陣列一樣遍歷,但並非真正的陣列
任意型別 any
在陣列中的應用
常見的做法是用任意型別 any
來表示陣列中的元素可以是任何型別:
const mixedArray: any[] = [1, 'hello', true, { name: 'John' }, [3, 4, 5]]
// 可以加入任何型別的元素
mixedArray.push(18)
mixedArray.push('world')
mixedArray.push({ age: 30 })
混合型別的陣列
如果陣列中的元素有不同的型別,我們可以使用聯合型別(Union Types)來表示這種情況:
let mixedArray: (number | string)[] = [1, "two", 3, "four"];
Readonly 陣列
你可以使用 ReadonlyArray<ElementType>
來表示唯讀的陣列:
let readOnlyNumbers: ReadonlyArray<number> = [1, 2, 3];
在介面中使用陣列
你可以在介面中定義一個陣列的型別,然後在物件中使用該型別:
interface Data {
values: number[];
names: string[];
}
let data: Data = {
values: [1, 2, 3],
names: ["Alice", "Bob"]
};