LoginSignup
3
0

More than 3 years have passed since last update.

TypeScriptのジェネリック型制約とデフォルト型

Last updated at Posted at 2020-05-28
type SomeType<T extends object = any> = {
  value: T;
};

使おうと思って調べていたライブラリのd.tsファイルを見ていたらこんな感じの型があった。読み方がわからなかったので調べた。

extends

まずは<T extends object>。ジェネリックでextendsを使うことによって、Tがとれる型の範囲を決めます。下記の例では、Tobjectextendsされているので、Tobject型、またはobjectのサブクラス型を取ることができます。

type SomeType<T extends object> = {
  value: T;
};

const hoge1: SomeType<object> = {
  value: { value: "object" },
};
// => ok

const hoge2: SomeType<string[]> = {
  value: [],
};
// => ok

const hoge3: SomeType<string> = {
  value: "record",
};
// => Type 'string' does not satisfy the constraint 'object'.

arrayobjectのサブクラスなので利用できますが、stringはサブクラスでないので使えません。

ちなみに型のヒエラルキーはこのようになっています。

prts_0301.png

3. All About Types - Programming TypeScript Book

デフォルト型

次にジェネリックのデフォルト型について見てみます。

type SomeType<T = object> = {
  value: T;
};

const hoge1: SomeType = {
  value: { value: "object" },
};
// => ok

const hoge2: SomeType<object> = {
  value: { value: "object" },
};
// => ok

const hoge3: SomeType<string> = {
  value: "string",
};
// => ok

ジェネリックのデフォルト型を設定しておくと、hoge1のように型利用時にジェネリック型を明示的に指定しなくても推論してくれます。デフォルト型はobjectになっていますが、extendsで制約されているわけではないので、string型も指定できます。

extends とデフォルト型

最後に冒頭に書いた型について。extendsで型を制約しつつ、デフォルト型を設定する場合、変数設定時等でジェネリック型を明示的に指定した際に制約が課され、指定しない場合はデフォルト型が適応されます。

type SomeType<T extends object = any> = {
  value: T;
};

const hoge1: SomeType = {
  value: "string",
};
// => ok

const hoge2: SomeType<string> = {
  value: "string",
};
// => Type 'string' does not satisfy the constraint 'object'.

const hoge3: SomeType<string[]> = {
  value: [],
};
// => ok

hoge1はジェネリック型を明示的にしていないため、Tany型になりますが、hoge2は明示的にstringを指定しているため、extends objectの制約でエラーになります。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0