TypeScript:データの型をざっくり定義してみた

TypeScript なのにざっくり定義するのは如何なものか、というのは承知の上でやってみました。

どれでも当てはまる様にしてみる

以下の定義が簡単ですね。

type AnyObj = { [prop: string]: string | number };

プロパティが文字と数値の他にもあるなら、| (OR) で追加します。
(流石に any は止めておく。)
以下の様に、どのデータでも当てはまる感じになります。

function example1(data: AnyObj) {
  // 何らかの処理
}

example1({
  name: 'kuma',
  date: '20211113',
});

example1({
  id: 9,
  file: 'image.png',
});

特定のプロパティは型を決める

プロパティによって決まった型に制限してみます。

// 必須項目のプロパティ
type RequiredProps = {
  id: number;
  title: string;
};

// 任意の文字列プロパティ
type StringPropNames
  = 'author'
  | 'publisher';
type StringProps = {
  [prop in StringPropNames]?: string;
};

// 任意の数値プロパティ
type NumberPropNames
  = 'price'
  | 'stock';
type NumberProps = {
  [prop in NumberPropNames]?: number;
};

// その他何でも
type OtherProps = {
  [prop: string]: string | number;
};

// データの型
type BookData = RequiredProps & StringProps & NumberProps & OtherProps;

プロパティを、一旦「必須」「文字列(プロパティが無くてもOK)」「数値(プロパティが無くてもOK)」と分けてから結合しましたが、要は

type BookData = {
  id: number;
  title: string;
  author?: string;
  publisher?: string;
  price?: number;
  stock?: number;
} & {
  [prop: string]: string | number;
};

という宣言と一緒です。

function example2(data: BookData) {
  // 何らかの処理
}

example2({
  id: 1,              // 必須
  title: 'kumakuma',  // 必須
  author: 'kuma',
                      // publisher は無くてもOK
  price: 100,
                      // stock は無くてもOK
  translator: 'kuma', // 未定義の文字列プロパティがあってもOK
});

というように、特定のプロパティは型を制限して他は何でも、という定義にできました。

コメント