TL;DR
- どうしても
anyを使うときは、スコープをできるだけ狭くし、他の部分の型安全性を損なわないようにする。 - 関数から
anyを返すのは絶対に避ける。
内容
スコープを狭くする
変数全体を any にすると、その変数を使うすべての箇所で型安全性が失われる。any は必要な式にだけ付ける。
// 🙅 Bad
const pizza: any = getPizza()
eatSalad(pizza)
pizza.slice() // 型安全でない
// 🙆 OK
const pizza = getPizza()
eatSalad(pizza as any)
pizza.slice() // 型安全@ts-ignore や @ts-expect-error でも型エラーを回避できる。これらのコメントが効くのは次の 1 行だけなので、他に影響しない。エラーがなくなったときにエラーになる @ts-expect-error のほうが望ましい。ただし、意図しない別のエラーが起きても気づけないので、頼りすぎないこと。
オブジェクトの場合も、オブジェクト全体ではなく個々のプロパティに as any を付けてスコープを狭める。
関数から any を返さない
関数が any を返すと、その呼び出し元の型安全性まで損なわれる。
function eatDinner1() {
const pizza: any = getPizza()
// ...
return pizza
} // 戻り値の型が any
function spiceItUp() {
const pizza = eatDinner1()
pizza.addRedPepperFlakes() // 型安全でない
}戻り値に型アノテーションを付けると、意図しない any を防げる。ただし、推論できる型を書きすぎないように注意する(項目18 推論可能な型でコードを乱雑にしない)。また、標準 API にも any を返すものがある。
JSON.parse(text: string, reviver?: (this: any, key: string, value: any) => any): anyLinter で検出する
typescript-eslint の recommended-type-checked を有効にすると、no-unsafe-assignment や no-unsafe-return などのルールが有効になり、any の拡散を検出できる。