type - TypeScriptキーワード一覧
スポンサーリンク
「type」キーワードは型のエイリアス(別名)を定義する際に用いられます。
概要
「type」は「型エイリアス宣言」で用いられるキーワードです。大まかには以下のような形式で用いられます。
type bindingIdentifier [typeParameters] = type;
「bindingIdentifier」にエイリアス(別名)として用いたい名前(識別子)、「=」の後ろの「type」に実際の型を指定します。「typeParameters」は、エイリアスをジェネリック型(generic type; 総称型)として扱いたい場合に指定します。具体的には以下のような構文になります。
type bindingIdentifier <typeParameter[, typeParameter[, ...]]> = type;
この構文において、「< >
」に囲まれる箇所に(typeParameter の位置に)「型パラメーター」となる名前を1つまたはコンマ区切りで複数指定します。
「型エイリアス宣言」の仕様
構文
(参照: TypeScript/spec.md 「3.10 Type Aliases」)
Declaration[Yield]: (抜粋・TypeScriptで追加)
TypeAliasDeclaration
NamespaceElement: (抜粋)
TypeAliasDeclaration
ExportNamespaceElement: (抜粋)
export TypeAliasDeclaration
ImplementationElement: (抜粋)
TypeAliasDeclaration
DeclarationElement: (抜粋)
TypeAliasDeclaration
ExportImplementationElement: (抜粋)
export TypeAliasDeclaration
ExportDeclarationElement: (抜粋)
export TypeAliasDeclaration
TypeAliasDeclaration:
type BindingIdentifier TypeParametersopt = Type ;
※ 構文パラメーター「Yield」は「TypeAliasDeclaration」では使用されません。
※ 「opt」は省略可能を意味します。
- Declaration[Yield]: TypeAliasDeclaration
- NamespaceElement: TypeAliasDeclaration
- ExportNamespaceElement: export TypeAliasDeclaration
- ImplementationElement: TypeAliasDeclaration
- DeclarationElement: TypeAliasDeclaration
- ExportImplementationElement: export TypeAliasDeclaration
- ExportDeclarationElement: export TypeAliasDeclaration
- 文法「TypeAliasDeclaration」は「Declaration」などの一部として扱われます。大まかには宣言構文を記述できる箇所か
export
キーワードとともにエクスポートする識別子として型エイリアス宣言を記述することができます。 - ※ 「
export default
」の構文(「ExportDefaultImplementationElement」など)には TypeAliasDeclaration の記述は許可されていません。default のエクスポートとしたい場合は型エイリアス宣言を別途記述したのち「export default XXXX;
」とする必要があります。 - TypeAliasDeclaration: type BindingIdentifier TypeParametersopt = Type ;
- 文法「TypeAliasDeclaration」はキーワード「type」の後に識別子(BindingIdentifier)、オプションで型パラメーター(TypeParameters)と続け、さらに等号「=」に続けて型(Type)を指定します。
- なお、構文上は末尾にセミコロン「;」が必要ですが、省略した場合でも記述方法により、ECMAScriptの仕様(ES2015 - 11.9 Automatic Semicolon Insertion)によって自動的に挿入されたものとみなします。
意味
「型エイリアス宣言」を行うと、宣言の行われた場所に対応する宣言空間(declaration scope)において、BindingIdentifier で指定した名前で型を用いることができるようにします。例えばモジュール(ES Module)で型エイリアス宣言をすれば、そのモジュール内でエイリアスを利用することができます。
また、キーワード「export」を伴った場合は、エイリアス宣言と同時に BindingIdentifier で指定した名前でその型をエクスポートします。名前空間上でのエクスポートであればその名前空間内の型識別子として、モジュール上でのエクスポートであれば import 文経由で型を利用することができます。
キーワード情報
- 「type」は識別子としては予約されていません。(ユーザー定義の識別子として利用できます。)
- 「type」は型名として予約されていません。(ユーザー定義の型名として利用できます。)
- 「type」という名前(単語)の出現箇所によって「識別子」として用いられているか「型エイリアス宣言」として用いられているかが判別できるため、コンパイラーに混同されることはありません。
詳細
型エイリアス宣言は特定の型(表現)に対して別名を与え、その名前で型を利用できるようにします。
// 特定の場面で利用する型として型エイリアスを作る
type CardId = string | number;
type CardName = string;
type CardData = any;
// 型エイリアスの利用例: 通常の型を指定する箇所で利用可能
function addCard(name: CardName, data: CardData): CardId {
...
}
...
// 型エイリアスに対する型チェックは元の型に従う
addCard('Tom', { pets: ['cat'] });
addCard(123, 456); // ERROR: TS2345: number 型は string 型に割り当てられない
特にunion type(共用体型)やintersection type(交差型)、mapped type(マップ型)、およびconditional type(型の条件分岐)などは必然的に記述量が多くなる型表現であるため、これらに対してエイリアスを定義すると記述量が減少でき、利便性の向上につながります。
// mapped type の型エイリアスの例(lib.d.ts より引用)
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
// conditional type の型エイリアスの例(lib.d.ts より引用)
type NonNullable<T> = T extends null | undefined ? never : T;
型エイリアスは任意の型の表現に対して別名を与える、という役割であるため、以下のように通常のオブジェクト型に対して利用することも可能です。
// オブジェクト型の型エイリアスの例
type PiyoObject = {
piyoPiyo: string;
piyoBar: number;
piyoMethod(): void;
};
ただしこの形式は、以下のように「interface」キーワードを利用した場合と酷似しています。
// オブジェクト型を interface で定義する例
interface PiyoObject {
piyoPiyo: string;
piyoBar: number;
piyoMethod(): void;
}
オブジェクト型をインターフェイスとして定義する場合は、型エイリアスとして定義する場合に比べて以下のメリットが存在します。
- インターフェイスでの定義は新たにオブジェクトとして名前を追加するため、エディターのヒント表示等で表示される型名を常にそのインターフェイス名とすることができる
- 型エイリアスの場合は一部を除き、エイリアス名ではなく元の型(表現)が表示されるため、場合によっては非常に長いヒント表示となってしまうことがあります。
- インターフェイスで定義する場合「extends」を用いて別の型の「subtype(部分型)」とすることができる
- 型エイリアスでは別の型をintersection type(交差型)で組み合わせることで結果的に「subtype」とすることはできます。
※ 型エイリアスで定義された型自体は、その内容が結果的にオブジェクト型になるのであれば「interface」文の「extends」句などでも用いることができます。(mapped typeやconditional typeなどの場合は型パラメーターに左右されずにオブジェクト型と確定するような一部の場合しか用いることができません。)
「インターフェイスは新たなオブジェクト型を定義する」「型エイリアスは単純に別名を与える」という考え方に基づくと、原則としてオブジェクト型の定義には「interface」を用いるのが良いと考えられます。
※ あくまでもmapped typeは型表現としての「オブジェクト型」ではないので、mapped typeを記述する場合は型エイリアスである必要があります。
※ 関数型の宣言については、シグネチャが1種類のみ(かつ他のプロパティーを持たない)である場合は型エイリアス宣言を用いるのが推奨されるようです(tslint の recommended 設定にも「callable-types」が含まれます)。2種類以上の場合はオーバーロード扱いとするためにインターフェイスを用いる必要があります。