1 minute read

学んだこと

ジェネリクスをつかって型を引数として受け取る

  • 関数を呼び出す際に型を定義することができる。
// <>の中の文字は何個も定義することができる

function copy<T, ...>(value: T): T{
  return value;
}

// 呼び出すときは、<>の中に型名を記入する
console.log(copy<string>("hello"))

extends を使って型パラメータに制約を付ける方法

// 型パラメータ名の後ろにextendsをつけることで型の制約をつけることができる。
// この場合、nameプロパティがあるかつstringに代入できる値であればいれることができる。
function copy<T extends { name: string }>(value: T): T{
  return value;
}

console.log(copy( { name: "Quill" } ));

keyof を使ってオブジェクトのキーのユニオン型を作成する方法

  • 型の中で使える演算子
    • key を結合し、ユニオン型にする役目がある
function copy<T extends { name: string }, U extends keyof T>(value: T, key: U): T{
  return value;
}

// この場合、以下の様になる
// 第一引数: nameが設定されているプロパティを設定する。(プロパティが追加されていてもOK)
// 第二引数: プロパティ内にある名前以外は受け付けない(プロパティ名以外はエラーとなる)
console.log(copy({ name: "Quill", age: 38 }, "name"))

Class に対してジェネリクスを使用する方法

function copy<T extends { name: string }, U extends keyof T>(value: T, key: U): T{
  return value;
}

console.log(copy({ name: "Quill", age: 38 }, "name"))

// クラスにもジェネリクスを使用することができる。
// クラス名の後に記述する
class LightDatabase<T extends string | number | boolean> {
  private data: T[] = [];
  add(item: T){
    this.data.push(item);
  }
  remove(item: T){
    this.data.splice(this.data.indexOf(item), 1);
  }
  get(){
    return this.data;
  }
}

const stringLightDatabase = new LightDatabase<string>();
stringLightDatabase.add("apple");
stringLightDatabase.add("banana");
stringLightDatabase.remove("grape");
stringLightDatabase.remove("banana");
console.log(stringLightDatabase.get())

interface や Type エイリアスに対してジェネリクスを使用する方法

  • Class と同様にジェネリクスを使って型を制限することができる
// インタフェース名の後ろに<>を追加
interface TmpDatabase<T> {
  id: number;
  data: T[];
}

// インタフェース呼び出し時に型を宣言する
const tmpDatabase: TmpDatabase<number> = {
  id: 3,
  data: [32]
}

Utility 型

  • TS が用意している汎用的なジェネリック型
interface Todo{
  title: string;
  text: string;
}

// interfaceにあるプロパティがすべてオプショナル型になる
// -> プロパティを設定する必要がなくなる
type Todoable = Partial<Todo>

// interfaceのプロパティがreadonlyになる
type ReadTodo = ReadOnly<Todo>

// Promiseの<>にある型名が返ってくる
const fetchData: Promise<string> = new Promise(resolve =>{
  setTimeout(()=>{
    resolve("hello");
  }, 3000);
})

// dataがstring型になる
fetchData.then(data =>{
  data.toUpperCase();
})

// 型を設定することで型の配列を作ることができる
const vegetables: Array<string> = ["Tomato", "Broccoli", "Asparagus"]