💡

[TypeScript]連想配列のブラケット記法で発生するTS 7053エラーの回避方法

2023/02/16に公開

結論:ChatGPTに聞いたら解決しました

周りに聞ける人がいなかったので、最近流行りのChatGPTに質問したところ
最適化したコードを返してくれました。

エラーになったコード

key名をtypeで固定した連想配列を動的に削除する処理でエラーが発生しました。

const FruitTags = ["Apple", "Banana", "Cherry", "Dorian"] as const;
type FruitTag = (typeof FruitTags)[number];
type TagMap<T> = {
  [key in FruitTag]: T;
};
type store = {
sales: TagMap<Models.sales[]>
buy:TagMap<Models.buy[]>
stock:TagMap<Models.stock[]>
}
// 省略
function getTag(x:any):FruitTag  => {
// タグ名を取得する処理
 return tag;
}
// 
const tag = getTag(x);
delete store.sales[tag] // TS(7053)エラー

型 '"Apple" | "Banana" | "Cherry" | "Dorian"' の式を使用して型 >'TagMap<Models.sales[]>' にインデックスを付けることはできないため、要素は暗黙的に 'any' 型になります。
プロパティ 'Apple' は型 'TagMap<Models.sales[]>' に存在しません。ts(7053)

getTag(x)の戻り値はFruitTagなので[key in FruitTag]に当てはまるのかと思いきや、エラーが返されてしまいました。

自分で試した記法

asで明示してみる

delete store.sales[tag as FruitTag] 

型 '"Apple" | "Banana" | "Cherry" | "Dorian"' の式を使用して型 >'TagMap<Models.sales[]>' にインデックスを付けることはできないため、要素は暗黙的に 'any' 型になります。
プロパティ 'Apple' は型 'TagMap<Models.sales[]>' に存在しません。ts(7053)

...同じエラーのままです🙁

ChatGPTに聞いてみた🧐

検索してもなかなか当てはまるコードが見つからなかったので、ChatGPTに聞いてみました!

以下のコードを最適化します。
TS7053エラーを回避するスマートな方法で
const tag = getTag(x);
delete store.sales[tag];

ChatGPTの解答:

TS7053エラーは、型推論が不十分であることを示しています。このエラーを回避するために、明示的に型を指定することができます。
以下は、deleteキーワードを使用してオブジェクトのプロパティを削除する際に、型アサーションを使用してエラーを回避する例です。

const tag = getTag(x);
const { sales } = store;
delete sales[tag as keyof typeof sales];

この例では、tag変数に明示的に型を指定することで、エラーを回避しています。また、typeof演算子を使用してsalesオブジェクトの型を取得し、これをkeyof演算子と組み合わせて、正しい型を取得しています。
このようにすることで、TS7053エラーを回避しながら、コードを最適化することができます。

日本語で解説もしてくれてすごい!😆

delete sales[tag as keyof typeof sales];に書き換えたところエラーがでなくなりました。

もちろん、これが唯一の正解ではないと思います。
前後のコードによってはもっとよい書き方はあるでしょう。

typescriptの解説はとても役に立ったので
これからはコードのお供にChatGPTを使ってみたいと思いました。

Discussion