TypeScript – TypeSafe な ArrayObject と 操作 refine #TypeScript

#TypeScript 下記ブログの refine版です https://dev.classmethod.jp/etc/typescript-typesafe-arrayobject/ 筋肉で汗臭いプログラミングをしている人たちを横目に、型レベルプログラミングでクレバー&クールに解決する
2019.08.26

TypeScript - TypeSafe な ArrayObject と 操作 refine

下記ブログの refine版です

TypeScript – TypeSafe な ArrayObject と 操作

環境

VSCode バージョン1.36.1 (1.36.1)

概要

T extends ... を利用しました

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

type TypeFactory<T extends TypeBase> = T;

const foo = { code: 100, label: "foo" } as const;
type Foo = TypeFactory<typeof foo>;

const bar = { code: 200, label: "bar" } as const;
type Bar = TypeFactory<typeof bar>;

type ServiceStatus = Foo | Bar;

// https://github.com/Microsoft/TypeScript/issues/13923#issue-205837616
type DeepReadonly<T> = { readonly [P in keyof T]: DeepReadonly<T[P]> };

type DRServiceStatus = DeepReadonly<ServiceStatus[]>;

const serviceStatusDic: DRServiceStatus = [
    { code: 100, label: "foo" },
    { code: 200, label: "bar" },
    // { cobe: 200, label: "bar" }, // エラー
    // { code: 300, label: "bar" }, // エラー
    // { code: 200, lightNovel: 'bar' }, // エラー
    // { code: 200, label: "f00" }, // エラー
    // { code: 100, label: "bar" } // エラー
];

// https://www.typescriptlang.org/docs/handbook/advanced-types.html 参考
const find = <T extends ServiceStatus, U extends keyof T>(o: T, k: U) => {
    // 省略
};
find(foo, "code");
find(bar, "code");
// find(bar, 'x'); // エラー
// find({}, "code"); // エラー

const find2 = <T extends DRServiceStatus, U extends ServiceStatus>(
    o: T,
    k: U
) => {
    // 省略
};
find2(serviceStatusDic, foo);
find2(serviceStatusDic, bar);
// find2({}, bar) // エラー
// find2(serviceStatusDic, {code: 1, label: 'bar'})  // エラー

const find3 = <T extends DRServiceStatus, U extends ServiceStatus["code"]>(
    o: T,
    k: U
) => {
    // 省略
};
find3(serviceStatusDic, 100);
find3(serviceStatusDic, 200);
// find3(serviceStatusDic, 300) // エラー

まとめ

筋肉で汗臭いプログラミングをしている人たちを横目に、型レベルプログラミングでクレバー&クールに解決する

https://qiita.com/hiruberuto/items/c65e7629d3b1597840d9

AltJS = TypeScript のみでは無いと思います
SPA = Angular, Vue, React のみでは無いと思います

いろいろな実装方法や考え方を、吸収できればと思います