• ..

NodeJS

    object 型

    instanceof Objectな値なら何でも入れることができる型です。
    型にはobjectを使います。

    const obj: object = {};

    構造化したオブジェクトを Interface で定義する

    ある程度構造化したobjectが使いたいなら、interfaceで型を作ります。以下はfoobarというプロパティを持つValue型の例です。

    interface Value {
      foo: number;
      bar: number;
    }
    
    const value: Value = {
      foo: 0,
      bar: 1
    };

    ちなみに、以下はbarは持っていないプロパティなのでエラーになります。結構厳密です。

    const value: Value = {
      foo: 0,
      bar: 1,
      bar: 2,
    };

    Interface で構造化したもののプロパティを変数からアクセスdけいるようにする

    例えば'foo'はどこからからやってきた変数propに入っている値だとして、value[prop]で取れそうですがこれはエラーになります。僕的にはできるようにしてほしいなと思うのですが、とりあえ今(2019-01)時点ではできません。
    これができるようにするにはインデックス署名をその Interface に追加する必要があります。

    以下は、value[prop]で値を取れるようにしたものです。
    [index: string]: number | string部分がインデックス署名ですが、これはstringが来た時にfoobarの値どちらかが取得できるということを表しています。このように、値側は取得できるうるすべての値をUnionなどで羅列する必要があります。

    interface Value {
      [index: string]: number | string;
      foo: number;
      bar: string;
    }

    また[index: string]部分は[index: number]とも定義できます。これはvalue[number]のようなアクセスの為に必要です

    Interface のプロパティを Partial 化する

    1部だけ

    Partial Propertyとは、あってもなくてもどちらでも構わないというようなプロパティのことです。これはプロパティ名の後:の代わりに?:とするだけです。

    試しにbarを Partial 化するとこうなります。無くてもエラーになりません。

    interface Value {
      foo: number;
      bar?: number;
    }
    
    const value: Value = {
      foo: 'foo'
    }

    すべてのプロパティを Partial 化

    すべてを Partial 化したいなら全てに一々?を付ける必要はありません。Partialという TypeScript 自身が提供している Generics 化を使うことですべてを Partial 化できます。

    interface Value {
      foo: number;
      bar: number;
    }
    
    type PartialValue = Partial<Value>;

    このpartialValueは、次のように書くのと同じ意味になります。

    interface PartialValue {
      foo?: number;
      bar?: number;
    }

    Record 型で一気に定義する

    すべてのプロパティが同じ型の時便利なのがRecord<P extends string, V>型です。Pは、UnionstringVはそれぞれプロパティとなる値を設定します。つまり、P = 'foo' | 'bar'V = numberの場合、それは{foo: number, bar: number}となります。
    つまり、次の2つはまったく同じ型になります。

    type Value = Record<'foo' | 'bar', number>;
    interface Value {
      foo: number;
      bar: number;
    }

    Interface の extends を使ってある構造を継承した新たな構造を作る

    以下はValueのプロパティにbarを増やしたものになります。extendsで継承しているのでfoobarの記述はいりません。

    interface ValueWithBaz extends Value {
      baz: number;
    }
    // 同じ
    interface ValueWithBaz {
      foo: number;
      bar: number;
      baz: number;
    }