【TypeScript】省略可能プロパティが省略されていないことを確認する(自作型)
TypeScriptはObject型を定義するときに、?
を付けることで省略可能であることを定義できます。
type Hoge = { foo: string, bar?: number };
これはこれで便利なのですが、場合によってはpropertyを指定し忘れることによるバグの原因にもなってしまいます。
type ManyProp = { a?: string, b?: string, c?: string, d?: string, e?: string };
const createManyProp = (someObject: any):ManyProp => {
const { foo: {a, b}, bar: {c, d}, e } = someObject;
return {
a: a,
b: b || undefined,
c: c,
d: d || 'default',
// 忘れ去られたe ←エラーにならず…
};
};
あるべき論でいえば「省略可能にするなよ」と言いたくなりますが、複雑な開発だと「大体の場所では省略可能としておきながら、ここだけは指定し忘れそうで怖い」みたいなことが起こります。
(自分の場合、いま開発しているものの中で関数をラップする開発があり、ラップ対象の関数の引数がいくつか省略可能としておきたいのですが、ラップする以上ちゃんと省略可能なものも含めてすべての引数を渡せていることを担保したいという要求がありました。)
今回作成した型~OptionalChecker~
ということで、こんな型を用意してあげる:
type OptionalKey<T> = { [k in keyof T]: undefined extends T[k] ? k : never }[keyof T];
type OptionalChecker<T> = T & { [k in OptionalKey<T>]: T[k] | undefined };
すると、エラーをはいてくれます。
type ManyProp = { a?: string, b?: string, c?: string, d?: string, e?: string };
const createManyProp = (someObject: any):OptionalChecker<ManyProp> => {
const { foo: {a, b}, bar: {c, d}, e } = someObject;
return {
a: a,
b: b || undefined,
c: c,
d: d || 'default',
// 忘れ去られたe ← !!!TypeError!!!
};
};
参考:コード全体
VSCodeとかに張り付けてみてね。
type OptionalKey<T> = { [k in keyof T]: undefined extends T[k] ? k : never }[keyof T];
type OptionalChecker<T> = T & { [k in OptionalKey<T>]: T[k] | undefined };
type ManyProp = { a?: string, b?: string, c?: string, d?: string, e?: string };
const createManyProp = (someObject: any):ManyProp => {
const { foo: {a, b}, bar: {c, d}, e } = someObject;
return {
a: a,
b: b || undefined,
c: c,
d: d || 'default',
// 忘れ去られたe ←エラーにならず…
};
};
const createManyProp_error = (someObject: any):OptionalChecker<ManyProp> => {
const { foo: {a, b}, bar: {c, d}, e } = someObject;
return {
a: a,
b: b || undefined,
c: c,
d: d || 'default',
// 忘れ去られたe ← !!!TypeError!!!
};
};