kouの技術的メモ

学習した内容の定着やアウトプット用に開設しました

TypeScript ジェネリクスと配列、オブジェクト

ジェネリクス(Generics)とは

データの型に束縛されず、型そのものをパラメータ化して扱うこと。

例えば以下のような二つの関数を一つにまとめたいとする。 しかし、型が違うので一緒にすることができない。

function a(x: string) {
  alert(x);
}
 
function b(x: number) {
  alert(x);
}
 
a("BELTLOGGER");
b(9);

そこでジェネリクスを使うとまとめられる。

   
function a<T>(x: T) {
  alert(x);
}
 
a<string>("BELTLOGGER");
a<number>(9);

配列の型

配列の書き方

> const arr1: number[] = [1, 2, 3];  //一般的にはこちらの書き方が多い
 [1,2,3]
> const arr2: Array<number> = [1, 2, 3];  //ジェネリクスを使った書き方
[1,2,3]

オブジェクトの型

const john: { name: string, age: number } = { name: 'John', age: 25 }; //オブジェクト宣言時の型定義

interface User {  //インターフェース文でも型定義できる
  name: string; 
  age?: number;  //ナンバー型。「?」を付けると省略可能なプロパティになる。
}
const jane: User = { name: 'Jane', age: 27 }; 
const Jack: User = { name: 'Jack' }; 

type Person = User;  /Type Aliasでインターフェース型を代入
const rick: Person = { name: 'Rick', age: 31 }; 

Type Aliasで型合成

interface Foo { hoge?: number, fuga: string }; 
interfaceBar{hoge:number };
interface Buz { piyo: string };

type FooBar1 = Foo & Bar;  // { hoge: number, fuga: string }
type FooBar2 = Foo | Bar;   // { hoge?: number, fuga: string } or { hoge: number }
type FooBuz1 = Foo & Buz;   // { hoge?: number, fuga: string, piyo: string }
type FooBuz2 = Foo | Buz; // { hoge?: number, fuga: string } or { piyo: string } 
type BarFooBuz = Bar & (Foo | Buz;  // { hoge: number, fuga: string } or { hoge: number, piyo: string }

・ [&]交差型(Intersection Type) ...... 複数の型をひとつにまとめたもの。 『&』を使う。合成し た型のすべてのプロパティを備えるが、同じ名前のプロパティが省略可能と必須だと、必須 が優先される。 ・ [ | ]共用体型(Union Type) ...... 渡された複数の型のいずれかが適応される型。『|』を使う

イミュータブルな 配列とオブジェクト

constで定義すると変数自体の再代入とかはできないが、実は配列とオブジェクトの各要素の上書きや追加はできてしまう。

> arr[0] = 7;
7
> arr
[7,2,3]

>constobj={a:1,b:2}; >obj.b=5;
5
> obj
{a:1,b:5}

オブジェクトや配列でもイミュータブルな変数を定義したいときは、TypeScript3.4以降ではReadOnlyな型が使用できるようになった。 書き方は以下。

> const arr1: ReadonlyArray<string> = ['foo', 'bar'];
 >constarr2:readonlystring[]=['foo','bar'];

> arr1[0] = 'buz'; // error TS2542 
> arr2[2] = 'buz'; // error TS2542

> const obj1: Readonly<{ foo: number }
> = { foo: 2 }; > obj1.foo = 8;  // error TS2540