この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
TypeScript - TypeSafe な ArrayObject と 操作 refine
下記ブログの refine版です
環境
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 のみでは無いと思います
いろいろな実装方法や考え方を、吸収できればと思います