Skip to content

Instantly share code, notes, and snippets.

@LeeDDHH
Created September 21, 2021 04:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeeDDHH/03c25b5f7ad5d28516f493cf2d741da0 to your computer and use it in GitHub Desktop.
Save LeeDDHH/03c25b5f7ad5d28516f493cf2d741da0 to your computer and use it in GitHub Desktop.
typescriptのジェネリックについて

ジェネリックとは

  • 型を抽象化するためのもの
  • 型引数を使用して、実際に利用されるまで型が確定しないクラスや関数を実現するためのもの

関数の場合

関数の実行時まで引数の型が確定しない

function a<T>(x: T) {
  console.log(x);
}

a<number>(2);

関数の内部で使用する場合

function b<T>() {
  var x: T = null;
  console.log(x)
}

a<number>():

複数の型引数を使う場合

function c<T,U> (t: T, u: U){
  console.log(t);
  console.log(u);
}

クラスの場合

基本的な型

class MyClass<T>{
  public name: T;
}

ジェネリックの制約

未知の型に対して、特定のプロパティを利用すると、コンパイルエラーになることがある

  • 型引数で型付けされたデータを使用すると、コンパイルエラーになることがある
const someObj = {
  someProperty: "some Text"
};

function someFunction<T>(t: T) {
  t.someProperty;
};

someFunction(someObj);
// error TS2339: Property 'someProperty' does not exist on type 'T'.
  • Tは未知の型なので、引数に someProperty が存在するかどうかは判断できない
    • エラーを解決するためには、ジェネリクスに制約を入れる必要がある

使用するプロパティが存在する定義をすることで、制約を設ける

  • 型引数に制約を追加するには、まず someProperty が存在することを型として定義する必要がある
interface X {
  someProperty: string
}

function someFunction<T extends X>(t: T) {
  t.someProperty;
};
  • 「Tの型は、X型もしくはXを継承した型である」という制約を付与する
    • extends を使って、型引数に制約を追加する
  • TypeScriptは「Structural typing(構造型型付け)」と呼ばれる、構造が同じであれば同じ型とみなす方式を取っている
    • 同じメンバーを持っており、構造が同じであれば、互換性のある型とみなされる

メンバーを指定して制約を追加することもできる

  • 利用するメンバーだけを指定して制約を付与する
function someFunction<T extends{ someProperty: "" }>(t: T){
  t.someProperty;
}

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment