はじめに
「読んで学ぶTypeScript」をちょっとずつ読み進めます!
今回は、配列についてです!
コーディングに慣れていないので、ところどころ用語を調べて記載しながら書きますmm
そのため、初心者の方が理解するには、助けになるかもしれません ![]()
JavaScriptの配列の特徴
配列はオブジェクト
- 配列はオブジェクトなので、プロパティの値が同じでも、インスタンスが異なると同一のものとは判定されない
//(例)プロパティの値が同じ二つの配列
const arrayA = [1, 2, 3];
const arrayB = [1, 2, 3];
// 結果はfalseになる
console.log(arrayA === arrayB);
共変性がある
- 共変:その型自身、もしくは、その部分型(subtype)が代入できること
あまりピンと来なかったので、深掘りします!
まず、部分型(subtype)とは?
-
基本型が持つすべての性質や振る舞い(メソッドやプロパティ)を持つ+新たな性質・振る舞いも持つ型
-
基本型(supertype):階層構造の上位に位置する型
-
// 基本型
interface Animal {
isAnimal: boolean;
}
// 部分型
interface Dog extends Animal {
isDog: boolean;
}
基本型と部分型の関係
- 基本型の変数には、それ自身とその部分型が代入できる
- 部分型の変数には、基本型は代入できない
- 部分型の変数が、基本型よりも多くのプロパティ等を要求する可能性があるため
//例
let pochi: Dog = { isAnimal: true, isDog: true }; // Dog型の変数
let animal: Animal = pochi; // 基本型の変数には、部分型(Dog型)の変数の代入OK
//^^^基本型
let animal: Animal = { isAnimal: true }; // Animal型の変数
let pochi: Dog = animal; // Error: 部分型の変数には、基本型の変数の代入NG
//^^^部分型
基本型と部分型については、ある程度性質は理解できました。
では、なぜ TypeScriptの配列は共変性を持つのでしょうか?
TypeScriptの配列と型安全性
- 本来、TypeScriptの配列型は、要素型の代入を許可せず不変であるべき
- しかし、JavaScriptとの互換性や実用性を優先するため、共変として扱われている
- +TypeScriptの配列はミュータブルな性質を持つ
-
ミュータブル:値を後で変更できる性質
-
配列がミュータブルな性質を持つ+共変として扱われると、型安全性が崩れるという問題がある
以下懸念される例です。
//例
const dogs: Dog[] = [pochi];
const animals: Animal[] = dogs; // Animal[]型の配列にDog型の配列を代入できてしまう(共変性による)
interface Animal {
isAnimal: boolean;
}
interface Dog extends Animal {
wanwan(): string; // メソッド
}
const pochi = {
isAnimal: true,
wanwan() {
return "wanwan"; // メソッドの実装
},
};
// Animal[]型の animals を通して、Dog型ではないオブジェクトを代入できてしまう!
animals[0] = { isAnimal: true }; // あとから書き換えられる(ミュータブル)
// ※同時に元のDog[]型であるdogsの要素が、Animal型のオブジェクトに書き換えられる
const mayBePochi: Dog = dogs[0];
mayBePochi.wanwan(); // JS実行時エラー: mayBePochi.wanwanがない
//mayBePochi は Dog型のはずなのに、実際には Animal型(wanwanを持たない)になっている
// 結果として実行時にエラーになる
配列の書き方
配列リテラルで書ける
そもそもリテラルって何?
- プログラム上でデータ型の値を直接記述できるように構文で定義されたもの
- よく利用される主要なデータ型・オブジェクトには、リテラルが用意されている
-
プリミティブ型:真偽値、数値、BigInt、文字列、null
- 例(文字列):同じ記号( "" or '' or ``)で囲んだ内容 → 文字列として扱う
-
オブジェクト:オブジェクト、配列、正規表現
- 例(オブジェクトリテラル):
{}(中カッコ)を書く → 新しくオブジェクトを作成
- 例(オブジェクトリテラル):
-
プリミティブ型:真偽値、数値、BigInt、文字列、null
リテラル表記を使うことで、冗長な表現を避けられる
配列もよく使われるオブジェクトの一つなので、リテラルが用意されている
配列リテラルの書き方
-
[]で値を,区切りで囲む → その値を持つArrayオブジェクトを作成-
Arrayオブジェクト:配列を扱う際に使う、組み込みのコンストラクター関数の1つ -
コンストラクター関数:新しくオブジェクトを作成するための雛形となる関数
-
// 配列リテラルで書く場合
let arr = [1, 2, 3];
// 配列リテラルを使わない場合
let arr2 = new Array(1, 2, 3);
さいごに
なんとなく使っていた配列の性質などが、改めて理解できました!
配列はメソッドが色々あるので、どんな処理ができるのか、また学んでみます ![]()
アドカレ2025が開催中!
今年もアドカレ開催中です ![]()
面白そうなカレンダーがたくさんです!
特設サイト ↓
ギフトカードや Airpods, iPadなど、豪華賞品すぎるプレゼントカレンダーは必見!
↓
参考
