Typescriptで様々な型を扱う
Typescriptでは型を定義できます。プリミティブ型だけでなく、classやinterface、配列、連想配列等を定義できます。
また、nullableにしていないのにnull
とundefined
が代入できてしまう問題も解決しましょう。
目次
型を付ける
シンプルに変数や引数に型をつける場合、変数: 型
と書きます。
const i: number = 100; const s: string = "hoge"; const arr: number[] = [1, 2, 3]; // any型は何でも受け付けるというもの const arr: any[] = [1, "hoge", null, () => {}];
型の書き方はJSDocと同じです。
複数の型を持つ可能性がある場合、|
で区切ります。
そのように複数のいずれかの型を受け入れる型をunion型と言います。
let a: number | string = 100; a = "hoge"; let b: Array<number | string> = [100, "fuga"]; const c: {[key: string]: number} = {hoge: 100, fuga: 200}; // (引数) => 戻り値 とすると関数そのものの型を定義できる function f(cb: (a: number) => boolean): boolean { return cb(100); }
関数に型を付ける
関数の引数や戻り値に型をつける場合も、同じように: 型
を書きます。
引数には引数名: 型
を、戻り値にはfunction f(...): 型
と書きます。
function f(a: number, b: string): boolean { return true; }
アロー関数の場合、(...): 型 => {}
のように書きます。
const f = () : boolean => { return true; }
classの型
classでは、Typescriptでclassを定義した場合は特に指定する必要はありません。普通にclassを作るだけで入力補完等が効くようになります。

しかし、最初はnull
を入れておいて、後からインスタンスを代入するなどの場合は、let hoge: Hoge = null;
のように型を指定する必要があります。
importする場合
classやinterfaceが外部にある場合、それらをimportする必要があります。
export interface Fuga { f(): boolean; } export class Hoge implements Fuga { private aa: string = "hoge"; public bb: number = 100; private internalF() { return 100; } f() { return true; } }
import { Hoge, Fuga } from "./hoge"; function f(hoge: Hoge, fuga: Fuga): void { // .... }
ジェネリクスの指定
ジェネリクスの場合、<>
の中に型を指定します。
function f(): Promise<boolean> { return new Promise((resolve) => { setTimeout(() => { resolve(true); }, 1000); }) }
より詳しい内容は下のページにあります。
特定の値だけ受け付ける
型だけでなく、特定の値だけを受け付けるようにしたい場合、そのままその値を書きます。
const hoge: "foo" | 100 = 100; const hige: "foo" | 100 = "foo"; const fuga: "foo" | 100 = 200; // Type '200' is not assignable to type '100 | "foo"'.
関数の引数
関数の引数にはデフォルト値や、省略可能化などを設定できます。
もし実引数を省略しても良い場合 (つまりundefined
となっても良い場合) は、引数名?
とします。
function f(hoge: number, fuga?: string) { if (fuga != undefined) { // ... } else { // ... } } // fuga? となっているため、エラーではない f(100);
もしデフォルト値がある場合は呼び出し側で実引数を省略できますが、その場合は?
を付けることはできません。省略できることが自明であるためです。
// fuga? とはしない function f(hoge: number, fuga: string = "abc") { console.log(fuga); } f(100);
ここで、undefined
でも良いということはfuga: string | undefined
で良いと思われそうですが、この2つは明確に異なります。
省略するには?
を明示する必要があります。
function f(fuga?: string) { // ... } f(); // OK function g(fuga: string | undefined) { // ... } g(); // NG fugaは省略できない g(undefined); // OK function h(fuga: string) { // ... } h(undefined); // OK! h(null); // OK! h(100); // NG 仮引数はstring
nullとundefinedの扱い
上の例でも出てきましたが、string | null
のような書き方をせずともnull
は代入できます。
const s: string = null; // OK const s: string = undefined; // OK
しかし、これは多くの場合で期待されるものではないと思います。いちいちnull
かどうかをチェックしてから動かす必要が出てくるためです。
これを回避するには、tsconfig.jsonに"strictNullChecks": true
を書き加えます。 (無い場合はpackage.jsonがあるフォルダに作成してください。)
{ "compilerOptions": { // nullやundefinedを厳密にチェックするオプション "strictNullChecks": true } }
これを設定すると、const s: string = null;
などが想定通りエラーとなります。
function h(hige: number) { console.log(hige); } h(undefined); // Argument of type 'undefined' is not assignable to parameter of type 'number'. h(null); // ほぼ同上 const s: string = null; // Type 'null' is not assignable to type 'string'. const ss: string = undefined; // ほぼ同上 const n: string | null = undefined; // ほぼ同上
型に別名をつける
C言語のtypedef
ように、type
を利用することで型に別名をつけることができます。
type 新しい型名 = 型
と書きます。
type MyString = string | null; const s: MyString = null; // 関数の型定義 type MyCallback = (a: number) => boolean; function f(cb: MyCallback): boolean { return cb(100); } // 連想配列の定義 type MyObj = { name: string, age: number, } const person: MyObj = { name: "Taro", age: 18, }
まとめ
Typescriptで指定する型は、JSDocで指定した型と同じです。型を指定することで、コンパイル時にエラーとすることができ、より安全なコードを書くことができます。
null
関連の扱いがデフォルトでは甘いため、ミスを防ぐために必ずnull
を厳密にチェックする設定しておきましょう。
