TypeScript – TypeSafe な ArrayObject と 操作

TypeScript - TypeSafe な ArrayObject と 操作

TypeSafe な ArrayObject と ArrayObject の操作
を考えました(あまり実用的では有りません)

環境

VSCode バージョン1.36.1 (1.36.1)

TypeScript とは

型安全で開発可能な AltJS です
Microsoft が主体で開発しています

TypeSafe ではない ArrayObject

const serviceStatusDic = [
  { code: 100, label: "foo" },
  { code: 200, label: "bar" }
];

どのあたりが TypeSafe ではない?

object の key の typo がありえる

もう少し頑張る

object は 任意組み合わせ(ホワイトリスト) にしたい

  • code が 100 の時は、label は foo
  • code が 200 の時は、label は bar

TypeSafe な ArrayObject

VSCode の言語を TypeScript にして貼り付けてみてください
警告がでます 💣

type Tpl = {
  code: number;
  label: string;
};

class Foo implements Tpl {
  code!: 100;
  label!: "foo";
}

class Bar implements Tpl {
  code!: 200;
  label!: "bar";
}

type ServiceStatus = Foo | Bar;

const serviceStatusDic: Readonly<ServiceStatus[]> = [
  { code: 100, label: "foo" }, // OK
  { code: 200, label: "bar" }, // OK
  { cobe: 200, label: "bar" }, // cobe なので エラーになる
  { code: 300, label: "bar" }, // 300 なので エラーになる
  { code: 200, lightNovel: 'bar' }, // なろう系 なので エラーになる
  { code: 200, label: "f00" }, // オレでなきゃ 見逃しちゃうね
  { code: 100, label: "bar" } // 100 と bar の組み合わせ なので エラーになる
];

TypeSafe な ArrayObject 操作

VSCode の言語を TypeScript にして貼り付けてみてください
警告がでます 💣

type Whitelist<T> = T[keyof T];
type CodeWhitelist = Whitelist<Pick<ServiceStatus, "code">>;
type LabelWhitelist = Whitelist<Pick<ServiceStatus, "label">>;

const matchCode = (c: CodeWhitelist) => (s: ServiceStatus) => s.code === c;
const _findMatchCodeFromServiceStatusDic = (c: CodeWhitelist) =>
  serviceStatusDic.find(matchCode(c));
const find = _findMatchCodeFromServiceStatusDic; // alias

// ---
find(100); // {code: 100, label: 'foo'}
find(200); // {code: 200, label: 'bar'}
find(999); // 999はエラーになる

const label100: LabelWhitelist = "foo";
const label200: LabelWhitelist = "bar";
const labelXxx: LabelWhitelist = "xxx"; // xxxはエラーになる

まとめ

別の回答もあるかもしれませんので、探してみてください