ホームページ > ウェブフロントエンド > jsチュートリアル > TypeScript の罠: 開発者が犯しやすい間違いとその回避方法

TypeScript の罠: 開発者が犯しやすい間違いとその回避方法

Mary-Kate Olsen
リリース: 2024-11-08 06:38:02
オリジナル
827 人が閲覧しました

TypeScript Traps: Top Mistakes Developers Make and How to Dodge Them

導入

TypeScript は、コードが実行される前にエラーを検出できる型チェックなどの追加機能を JavaScript に追加するため、開発者の間で人気の選択肢となっています。各変数に特定の型があることを確認することで、TypeScript はよくある間違いを防ぎ、特に大規模なプロジェクトでコードを理解し、操作しやすくするのに役立ちます。

しかし、TypeScript を学習し始めると、よくある問題に遭遇することがよくあります。これらの間違いにより、コードが読みにくくなったり、TypeScript で回避できるはずのバグが発生したりする可能性があります。これらの間違いとその回避方法を学ぶことは、コードの品質に大きな違いをもたらす可能性があります。これにより、よりクリーンで安全なコードを作成できるようになり、後でデバッグする時間を節約できます。このガイドでは、TypeScript の最も一般的な間違いを説明し、それらを回避するための実践的なヒントを提供します。

間違い #1: 型アサーションの誤用

型アサーションとは何ですか?

TypeScript では、型アサーション は TypeScript に「信じてください、この変数がどのような型であるべきか知っています」と伝える方法です。たとえば、TypeScript が何かの型を不明な場合は、型アサーションを使用して特定の型として動作させることができます。

これは簡単な例です:

let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この場合、TypeScript に「その値は文字列であることがわかっています」と伝えているため、TypeScript で文字列機能 (.length など) を使用できるようになります。

型アサーションに関する一般的な問題

型アサーションは便利ですが、誤用すると問題を引き起こす可能性もあります。 適切なチェックを行わずに TypeScript に強制的に変数を特定の型として扱うを行うと、特に型が実際に想定しているものと異なる場合に、コード内でエラーが発生する可能性があります。

例:

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここでは、値が文字列であることを TypeScript に伝えていますが、実際には数値です。これにより TypeScript ではエラーが表示されませんが、コードが実際に実行されるときに問題が発生し、予期しないランタイム エラーが発生する可能性があります。

型アサーションの使いすぎが危険な理由

型アサーションを過度に使用すると、TypeScript がエラーをキャッチする機能の一部を失うため、問題が発生する可能性があります。型アサーションは、実際にどのような型であるかを TypeScript に「無視」するように指示します。これにより、そもそも TypeScript を使用する目的が無効になる可能性があります。 TypeScript はエラーを検出することを目的としていますが、型をアサートし続けると問題を見落としたり、バグを見逃したりする可能性があります。

この間違いを避ける方法

  1. 可能な場合は型推論を使用する: TypeScript は多くの場合、独自に型を把握できます。アサーションを使用する代わりに、可能な場合は TypeScript に型を推測させます。

  2. 不必要な any の使用を避ける: any 型を使用すると、型アサーションを使用したくなる可能性がありますが、any は型安全性を取り除きます。代わりに特定の型を使用すると、アサーションの必要性が減ります。

  3. 型アサーションの前にチェックを追加: 型が不明な場合は、まずそれを確認してください。例:

let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. any の代わりに unknown を使用する: TypeScript では使用前に型を確認する必要があるため、unknown 型はどの型よりも安全であり、安全でないアサーションを回避するのに役立ちます。

型アサーションは便利なツールですが、慎重かつ控えめに使用する必要があります。これらのベスト プラクティスに従うことで、TypeScript コードの信頼性を高め、実行時エラーのリスクを軽減できます。

間違い #2: any タイプの使いすぎ

任意のタイプとは何ですか?

TypeScript では、any 型は TypeScript に「これがどのような型であるかは知りません、または気にしません」と伝える手段です。変数の型を any に設定すると、TypeScript はその変数の型のチェックを停止します。これは、TypeScript がエラーをスローすることなく、文字列、数値、オブジェクトなどとして使用して、ほとんど何でもできることを意味します。

例:

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

なぜ問題が発生するのか

どれも便利そうに見えますが、TypeScript の安全機能を無効にするため、問題が発生する可能性があります。 TypeScript の重要な点は、正しい型を使用していることを確認してエラーを検出できるようにすることです。ただし、any を使用すると、TypeScript はその変数のエラーをチェックできず、バグが発生する可能性があります。

例:

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この場合、value は any であるため、TypeScript では value が数値であっても value.toUpperCase() が許可され、コードを実行しようとするとエラーが発生します。

開発者がいずれかを使用する一般的な理由

  1. クイックフィックス: 開発者は、エラーをすぐに解消するためだけにタイプを any に設定することがあります。
  2. 不確実な型: データの型が明確でない場合、開発者は正しい型を理解する代わりに任意の型を使用する可能性があります。
  3. 複雑なデータ: 複数のプロパティを持つ API 応答など、データが複雑な場合、開発者は構造の入力を避けるためにいずれかを使用することがあります。

このような場合に any を使用すると簡単に見えるかもしれませんが、長期的には大きな問題を引き起こすことがよくあります。

使いすぎを避ける方法

  1. any の代わりに不明な型を使用する: 使用する前に型を確認する必要があるため、不明な型の方が安全です。不明の場合、TypeScript は変数を使用する前に、その変数が特定の型であることを確認することを強制します。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 特定の型を定義: 各変数の正確な型を定義してみてください。たとえば、値が常に文字列であることがわかっている場合は、any の代わりに string を使用します。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 複雑なデータにインターフェイスを使用する: オブジェクトまたは複雑なデータの場合、構造を記述するインターフェイスを作成します。このようにして、TypeScript は各プロパティをチェックし、データが期待したものと一致していることを確認できます。
   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. any は最後の手段としてのみ使用してください: どうしても any を使用する必要がある場合は、コードのごく一部に限定し、それが必要な理由を説明するコメントを追加してください。

未知の型または特定の型を使用せずにコードを安全にし、予期しないエラーのリスクを軽減し、TypeScript コードをより強力で信頼性の高いものにすることができます。

間違い #3: すべてと未知のものを混同する

任意と不明の違いは何ですか?

TypeScript では、any とunknown の両方が、変数の正確な型がわからないときに使用できる型です。ただし、重要な違いがあります:

  • any: 型チェックを行わずに変数に対してあらゆる操作を行うことができます。基本的に TypeScript の安全機能をオフにします。
  • unknown: 変数を特定の方法で使用する前に型を確認する必要があります。 TypeScript では、その型を確認するまで意味をなさない方法での使用が防止されるため、より安全なオプションです。

なぜ未知の方が安全であることが多いのか

変数を使用する前に型のチェックが強制されるため、unknown を使用する方が通常は他の方法よりも安全です。これは、どのタイプを操作しているかわからないときに発生する可能性のあるエラーを防ぐのに役立ちます。

たとえば、変数を操作していて、それが文字列なのか数値なのかわからないと想像してください。

let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここでは、値が不明であるため、文字列であることを確認するまで TypeScript では value.toUpperCase() を使用できません。型チェックを行わずに toUpperCase() を使用しようとすると、TypeScript によってエラーが表示され、実行時のバグを防ぐことができます。

一方、次の場合:

let value: any = "Hello!";
console.log(value.toUpperCase()); // This is fine
value = 42;
console.log(value.toUpperCase()); // TypeScript won’t catch this, but it will cause an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

後で値が数値になった場合、このコードは実行時にエラーをスローし、TypeScript はそれについて警告しません。不明を使用すると、最初に型チェックが必要になるため、この問題を回避できます。

任意か不明かを選択する方法

  1. 型が不確実な場合は、unknown を使用します: 変数の型が不明で、使用前にチェックを実行する必要がある場合は、unknown を使用します。 TypeScript では、特定の操作を行う前に必ず型をチェックするため、より安全です。

  2. 可能な場合は any を避ける: any は TypeScript の型チェックを削除するため、最後の手段としてください。 any は、型をまったくチェックする必要がないと確信できる場合にのみ使用し、実際には問題ありません。

  3. unknown を使用して型チェックを追加します:unknown を使用するときは、必ず使用する前にチェックを追加してください。これにより、TypeScript の安全機能がアクティブな状態に保たれ、予期しないバグを防ぐことができます。

  4. 特定の型を優先: 型が何になるかわかっている場合は、any または未知の型の代わりにその型を使用します。これにより、コードがより予測可能になり、理解しやすくなります。

unknown を使用すると、コードをより安全に保ち、何らかのコードですり抜ける可能性のあるエラーを防ぐことができます。これにより、作業しているデータの種類を常に把握するなどの良い習慣が促進され、より信頼性の高い TypeScript コードを作成できるようになります。

間違い #4: Null 値と未定義値を無視する

TypeScript の Null と Unknown について理解する

TypeScript では、null未定義 は、「空」または「未設定」の値を表します。

  • null は、フォーム内のフィールドを意図的に空白のままにする場合など、意図的に値を持たない場合に使用されます。
  • 未定義 は、変数が作成されても値が与えられていない場合など、値がまだ割り当てられていないことを意味します。

これらの「空」の値を無視すると、null または未定義の可能性のある変数を使用しようとしたときにエラーが発生する可能性があります。

Null および未定義の一般的なエラー

TypeScript が null または未定義を考慮していない場合、変数に値があるかのように変数を使用しようとしましたが、値が存在しないことが判明する可能性があります。これにより、ランタイム エラー (コードの実行時に発生するエラー) が発生する可能性があります。

例:

let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここでは、user が null であるため、user.name にアクセスしようとするとエラーがスローされます。値が null または未定義である可能性があるケースを処理しないと、コードが予期せず破損する可能性があります。

この間違いを避ける方法

  1. オプションのチェーンを使用する (?.): オプションのチェーンは、オブジェクトが null または未定義の場合でもプロパティに安全にアクセスできるようにする TypeScript の機能です。 ?. を使用すると、TypeScript はプロパティにアクセスする前にオブジェクトが存在するかどうかを確認します。そうでない場合は、エラーをスローするのではなく、単に未定義を返します。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 非 Null アサーション (!): コード内の特定の時点で、値が null または未定義ではないことが確実にわかっている場合がありますが、TypeScript ではそれがわかりません。 非 null アサーション (!) を使用して、TypeScript に「この値は null または未定義ではないことを知っています」と伝えることができます。ただし、値が null であることが判明した場合でもエラーが発生するため、これは慎重に使用してください。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 厳密な Null チェックを有効にする: TypeScript の strictNullChecks 設定は、null および未定義のケースを確実に処理するのに役立ちます。このオプションがオンの場合、TypeScript では、null または未定義の可能性がある変数を最初にチェックせずに使用することができなくなり、エラーを早期に発見するのに役立ちます。

厳密な null チェックをオンにするには、tsconfig.json ファイルに "strictNullChecks": true を追加します。こうすることで、TypeScript では null と未定義を適切に処理する必要が生じ、コードがより安全になります。

null と未定義の値を適切に処理すると、バグを回避し、空の値が発生したときにコードが壊れるのを防ぐことができます。オプションのチェーン、非 null アサーション、厳密な null チェックを使用すると、TypeScript コードの信頼性が高まり、操作が容易になります。

間違い #5: 型アノテーションの間違った使用

型アノテーションとは何ですか?

型アノテーションは、変数、関数、またはパラメーターにどのような型を持たせる必要があるかを TypeScript に指示するときに使用します。たとえば、変数が常に数値であることがわかっている場合は、次のように書くことができます。

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これにより、年齢が数字であることが明らかになります。 TypeScript は、この情報を使用して、age を文字列などの別の型として使用しようとした場合の間違いを検出します。

型アノテーションに関するよくある間違い

場合によっては、次のような型アノテーションで間違いを犯すことがあります。

  1. 間違った型の割り当て: たとえば、実際には数値であるにもかかわらず、文字列であると表現します。これにより、エラーや混乱が生じる可能性があります。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 過剰な注釈: これは、TypeScript がすでに型を認識している場合でも、あらゆる場所に型の注釈を追加する場合です。 TypeScript は多くの場合、独自に型を理解できるほど賢いため、追加の注釈が必ずしも必要というわけではありません。追加する型注釈が多すぎると、コードが乱雑に見え、読みにくくなる可能性があります。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

型アノテーションの使いすぎが混乱を招く理由

注釈を多用すると、コードが繰り返してわかりにくくなる可能性があります。 TypeScript は、変数の値に基づいて変数の型を自動的に「推測」します。したがって、TypeScript が正しく型を推測できる場合は、毎回型を書き出す必要はありません。

たとえば、次のコード:

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

TypeScript は isComplete がブール値であることをすでに理解しているため、: boolean を追加する必要はありません。

型アノテーションの誤った使用を避ける方法

  1. 可能な場合は TypeScript で型を推論させます: 値を変数に直接割り当てる場合は、型の注釈をスキップできます。 TypeScript は値に基づいて型を自動的に検出します。
let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 必要な場合にのみ注釈を使用する: 関数パラメーターや複雑なオブジェクトなど、TypeScript が独自に型を推論できない場合に型注釈を追加します。
let value: any = "Hello!";
console.log(value.toUpperCase()); // This is fine
value = 42;
console.log(value.toUpperCase()); // TypeScript won’t catch this, but it will cause an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 型の精度を確認する: 型の注釈を追加する場合は、それらが正しいことを確認してください。実際には数値であるのに文字列と呼ぶなどの不一致を避けるために、型が使用されている実際の値と一致していることを再確認してください。

可能な場合は TypeScript に型を処理させ、必要な場合にのみ明確な注釈を追加すると、コードがすっきりして読みやすくなり、エラーが発生しにくくなります。これにより、TypeScript コードがシンプルで理解しやすくなります!

間違い #6: 構造型付けを忘れる

構造型付けとは何ですか?

TypeScript は 構造的型付け と呼ばれるものを使用します。つまり、TypeScript は、型の名前ではなく、オブジェクトの形状や構造を考慮して、特定の型と互換性があるかどうかを判断します。

言い換えると、2 つのオブジェクトが同じプロパティと型を持つ場合、TypeScript は、たとえ名前が異なっていても、それらを同じものとみなします。

例:

   let value: unknown = "Hello!";
   if (typeof value === "string") {
       console.log(value.toUpperCase());
   }
ログイン後にコピー
ログイン後にコピー

ここで、座標とanotherCoownedは同じ構造を持っているため、TypeScriptはそれらを互換性があると見なします。 TypeScript は、anotherCoowned が Point と呼ばれていなくても気にしません。数値型の x プロパティと y プロパティがあるかどうかのみをチェックします。

構造型付けでよくある間違い

よくある間違いは、TypeScript が 名目上の型付け (名前に基づく型) を使用していると想定することです。名目上の型付けでは、互換性を保つには、2 つのものが名前的にまったく同じ型である必要があります。しかし、TypeScript の構造システムでは、形状が一致する場合、TypeScript はそれらを同じ型として扱います。

たとえば、開発者は、Point タイプのオブジェクトのみを座標に割り当てることができると考えるかもしれません。ただし、TypeScript では、型名に関係なく、同じ構造を持つ任意のオブジェクトが許可されます。これは、コードのさまざまな部分から一致する形状を持つオブジェクトを同じ型と見なすことができるため、構造型付けに慣れていない場合は混乱する可能性があります。

構造型付けの間違いを避ける方法

  1. 形状ベースのアプローチを理解する: TypeScript は名前よりも構造 (プロパティと型) を重視することに注意してください。オブジェクトの型名ではなく、オブジェクトが持つプロパティに注目してください。

  2. 追加のプロパティには注意してください: オブジェクトに追加のプロパティを追加しても、場合によっては期待される型と一致する可能性があります。混乱を避けるために、オブジェクトには特定の型に必要なプロパティのみが含まれていることを確認してください。

  3. インターフェイスと型エイリアスを使用して構造を強制する: TypeScript は構造型付けに柔軟ですが、インターフェイス または 型エイリアス を作成すると定義に役立ちます構造を明確にし、意図した形状を他の開発者に伝えます。これを実践すると、コードがより理解しやすくなります。

let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 必要な場合は型チェックに頼る: TypeScript の構造的型付けは柔軟性を高めるために非常に強力ですが、一致する構造を持つオブジェクトがどのように相互作用するかを認識することが依然として重要です。より厳密にしたい場合は、各型が一意であることを保証するクラスまたはテクニックを使用できます。

TypeScript の構造型型付けシステムは柔軟性を備えていますが、予期せぬ事態を避けるためにはその仕組みを理解することが重要です。型の形状に焦点を当て、インターフェイスまたは型エイリアスを使用することで、コードを明確で信頼性のあるものに保ちながら、このシステムを最大限に活用できます。

間違い #7: オブジェクトの形状を間違って定義する

オブジェクトの形状の定義が重要な理由

TypeScript では、オブジェクトを作成するときに、そのオブジェクトにどのようなプロパティがあり、各プロパティがどのような型であるべきかを定義する必要があります。これをオブジェクトの形状の定義と呼びます。形状が適切に定義されていない場合、ランタイム エラー、つまりコードの実行時に発生するエラーが発生する可能性があります。

たとえば、オブジェクトには名前と年齢を指定する必要があると指定したが、年齢を追加するのを忘れた場合、TypeScript は場合によってはそれをスライドさせますが、後で age を使用しようとするとコードが中断する可能性があります。

現実世界の例

名前と年齢が必要な User オブジェクトを定義しているとします。

let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、ユーザーを作成しても年齢を追加するのを忘れると、問題が発生する可能性があります。

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これは単純な間違いですが、年齢が常に存在すると期待すると問題が発生する可能性があります。オブジェクトの形状を正しく定義しないと、重要なプロパティを誤ってスキップしてしまい、それらのプロパティにアクセスしようとするとエラーが発生する可能性があります。

この間違いを避ける方法

  1. インターフェイスと型エイリアスの使用: TypeScript の インターフェイス または 型エイリアス を使用して、オブジェクトの構造を明確に定義します。これにより、オブジェクトを作成するたびに、すべての必須フィールドが適切に配置されるようになります。
   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 必要な場合はオプションのプロパティを使用する: プロパティが常に必須ではない場合は、? を使用してオプションとしてマークできます。こうすることで、省略しても TypeScript は文句を言いませんが、他の必須フィールドもチェックします。
let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. ユーティリティ タイプを活用: TypeScript には、柔軟な形状をサポートする Partial などの組み込みユーティリティ タイプがあります。たとえば、オブジェクトの一部のみを更新する場合は、Partial を使用できます。プロパティを省略できるようにします。
let value: any = "Hello!";
console.log(value.toUpperCase()); // This is fine
value = 42;
console.log(value.toUpperCase()); // TypeScript won’t catch this, but it will cause an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 必須プロパティをダブルチェックする: オブジェクトを定義または使用するときは、オブジェクトに必要なフィールドがすべて含まれていることを常に確認してください。必須のプロパティが欠落していると問題が発生する可能性があるため、オブジェクトが定義された形状と一致していることを確認することを習慣にしてください。

オブジェクトの形状を慎重に定義することで、各オブジェクトに必須フィールドが確実に含まれるようになり、コードの信頼性が高まり、エラーのリスクが軽減されます。インターフェイス、オプションのプロパティ、ユーティリティ タイプなどの TypeScript のツールを使用すると、形状を正確に定義し、コードの保守が容易になります。

間違い #8: 列挙型の使いすぎ

列挙型とは何ですか?

TypeScript では、列挙型 は名前付きの値のセットを定義する方法です。これらを使用すると、関連する値を 1 つの名前でグループ化できます。例:

   let value: unknown = "Hello!";
   if (typeof value === "string") {
       console.log(value.toUpperCase());
   }
ログイン後にコピー
ログイン後にコピー

列挙型は、タスクのステータスなど、限られた値のセットを表す必要がある場合に役立ちます。ただし、列挙型を多用しすぎると、コードが必要以上に複雑になる場合があります。

列挙型の使いすぎが問題となる理由

  1. コードが読みにくくなる: enum を使用する場合、enum 値の名前を覚える必要があるため、不必要に複雑になる可能性があります。例えば:
   let value: string = "Hello!";
ログイン後にコピー

これは問題ないように見えますが、あらゆる場所で列挙型を使用すると、特に列挙型の定義に慣れていない開発者にとって、コードをすぐに理解するのが難しくなる可能性があります。

  1. コードのメンテナンスが増加します: コード全体で列挙型を使用すると、後から値を更新または変更することがより困難になる可能性があります。多くの場所で列挙型を検索して更新する必要がある場合があり、追加の作業が発生します。

  2. 不必要な抽象化: 列挙型によって、不要な抽象化レベルが追加される場合があります。たとえば、列挙型を必要とせずに、単純な文字列や数値でも同様に機能します。

列挙型の過剰使用を避ける方法

  1. 代わりに共用体型を使用します: 少数の値のセットのみが必要な場合は、列挙型の代わりに 共用タイプ を使用することを検討してください。ユニオン型はシンプルで保守が簡単です。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、Status は単に可能な値のセットです。これは列挙型よりも単純でありながら、型安全性を提供します。

  1. 単純な場合には文字列リテラルを使用します: 値が単純な文字列の場合は、列挙型の代わりに文字列リテラルを使用します。例えば:
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これにより、列挙型全体を作成する必要がなく、物事がシンプルかつ明確になります。

  1. 特定の場合には列挙型を使用する: 列挙型は、列挙型にメソッドを追加する場合や、値をより説明する必要がある場合など、より複雑なものを表現する必要がある場合に便利です。たとえば、追加の機能が必要なステータス コードのセットを扱う場合は、列挙型が合理的である可能性があります。ただし、単純な値のセットの場合は、それらを避けることをお勧めします。

列挙型を使用する場合

列挙型は次のような場合に最適です。

  • コード内のさまざまな場所で使用される、関連する値の名前付きコレクションが必要です。
  • 値に関連付けられた機能がさらに必要です (メソッドや計算されたプロパティなど)。

しかし、単純な値のセットの場合は、共用体型または文字列リテラルを使用する方がより優れた単純な解決策であることがよくあります。

列挙型の過度の使用を避けることで、コードが読みやすく、保守し、理解しやすくなり、よりクリーンで効率的になります。

間違い #9: ジェネリック医薬品の誤解

ジェネリックとは何ですか?

TypeScript のジェネリックは、型の安全性を維持しながら、あらゆる型で動作できる再利用可能なコードを作成する方法です。これらを使用すると、TypeScript の型チェックの利点を損なうことなく、さまざまな型を処理できる関数、クラス、またはインターフェイスを作成できます。

例:

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この場合、T は関数を呼び出すときに決定される型のプレースホルダーです。任意の型 (文字列、数値など) を渡すことができ、TypeScript は型が一致することを確認します。

ジェネリック医薬品に関するよくある間違い

  1. 間違った型制約: 開発者がジェネリックに制約を追加しようとして、間違ったものを追加することがあります。たとえば、制限が厳しすぎる制約や、使用している関数やクラスにとって意味をなさない制約を使用しようとする場合があります。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここでは、T は文字列であるように制約されており、これは長さプロパティにとって意味があります。ただし、不要な制約または不適切な制約を使用すると、他の型では関数が壊れる可能性があります。

  1. コードが複雑になりすぎる: ジェネリックスを誤ってまたは不必要に使用すると、コードが必要以上に複雑になる可能性があります。たとえば、より単純なソリューションでも同様に機能するジェネリック型または関数を作成できます。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

任意の型の 2 つの値を結合するだけなので、この関数は汎用である必要はありません。ジェネリックを使用せずにこれを簡素化できます。

ジェネリック医薬品の誤解を避けるには

  1. 必要な場合にのみジェネリックを使用する: ジェネリックは常に必要というわけではありません。コードがさまざまな型を扱う必要がない場合は、特定の型を使用することをお勧めします。ジェネリックは強力ですが、価値を付加する場合にのみ使用してください。

  2. 型制約を理解する: ジェネリックスを使用するときは、制約が意味をなしていることを確認してください。制限する必要がある種類のみを制限します。たとえば、配列を操作している場合は、T[] または Array を使用します。制約として。

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. 可能な限り簡素化: 不要なジェネリックスを使用してコードを複雑にしすぎないでください。単純な型 (文字列や数値など) が正常に機能する場合は、それをジェネリックで一般化しようとしないでください。関数またはクラスをさまざまな型に柔軟に対応させたい場合は、ジェネリックを使用します。

  2. デフォルトのジェネリックを使用する: ジェネリックを使いやすくしたい場合は、ユーザーがデフォルトの型を指定しない場合に備えて、デフォルトの型を割り当てることができます。

let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、ユーザーが型を指定しない場合、T はデフォルトで文字列になります。

重要なポイント

  • ジェネリックは再利用可能で柔軟なコードに最適ですが、正しく使用しないと混乱を招く可能性があります。
  • 型の制約に注意してください。型を過度に制限したり、不適切に制限したりしないでください。
  • ジェネリックスは、コードに価値を追加する場合にのみ使用してください。多くの場合、単純なタイプで十分です。

ジェネリックがどのように機能するのか、いつ使用するのかを理解することで、よくある間違いを回避し、コードをより柔軟で読みやすく、保守しやすくすることができます。

間違い #10: TypeScript 構成オプションを無視する

TypeScript 構成オプションとは何ですか?

TypeScript には、tsconfig.json という 設定ファイル があり、ここでさまざまなオプションを設定して、TypeScript がコードをコンパイルする方法をカスタマイズできます。この構成により、より厳格なルールを適用し、コード内で問題が発生する前に潜在的なエラーを早期に検出できます。

構成を無視すると問題が生じる理由

TypeScript の構成に注意を払わないと、コードのバグや問題につながる可能性のある特定のエラーや問題が検出されない可能性があります。たとえば、TypeScript を使用すると、適切な設定が有効であれば、通常は不正としてフラグが立てられるコードを作成できる可能性があります。

これらの設定を無視すると、重要な警告を見逃してコードの安全性が低下する可能性があります。

注意すべき主要な TypeScript 構成オプション

  1. strict: これは、複数の重要な厳密なチェックを一度に有効にする特別な設定です。これは、コードがタイプセーフであり、いかなる種類のルーズまたは弱い型付けにも依存しないことを保証するのに役立ちます。

重要な理由: strict が有効になっている場合、TypeScript は初期化されていない変数や null チェックなどをチェックします。これにより、潜在的な問題を早期に発見することができます。

let value: any = "Hello, world!";
let stringLength = (value as string).length;
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. noImplicitAny: この設定により、明示的に宣言されていない限り、TypeScript で変数、パラメーター、または戻り値を any として型指定できなくなります。 any を使用すると、TypeScript の型チェック システムをバイパスして、任意の値を割り当てることができます。

重要な理由: noImplicitAny を使用すると、TypeScript で型の指定が強制され、誤って使用したり、型チェックで検出できる潜在的なバグを見逃したりすることがなくなります。

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  1. strictNullChecks: この設定を有効にすると、明示的に指定しない限り、null と unknown がどの型の有効な値としても扱われなくなります。これは、誤って null または未定義を使用しようとすることによって発生する可能性のあるバグを防ぐのに役立ちます。

重要な理由: この設定を使用しないと、TypeScript では null と未定義を任意の変数に割り当てることができ、実行時エラーが発生する可能性があります。

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この間違いを避ける方法

  1. Strict モードを有効にする: tsconfig.json で strict フラグを常に有効にします。これにより、noImplicitAny や strictNullChecks など、いくつかの便利な設定が自動的に有効になります。これは、コードが可能な限り安全でエラーがないことを保証する最良の方法の 1 つです。

  2. 設定の確認とカスタマイズ: TypeScript コンパイラ オプションの完全なリストを確認してください。プロジェクトのニーズに合わせてカスタマイズします。特定のチェックを有効または無効にして、コードの信頼性と保守性を高めることができます。

  3. 常に noImplicitAny を有効にする: 絶対に必要な場合を除き、any タイプは避けてください。 noImplicitAny を有効にすると、変数の型について考える必要が生じ、コードがより安全になります。

  4. strictNullChecks を使用して Null エラーをキャッチ: Null 値は、慎重に扱わないと簡単にバグを引き起こす可能性があります。 strictNullChecks を有効にすることにより、null または未定義が問題を引き起こす可能性のある場所に滑り込まないようにすることができます。

重要なポイント

  • TypeScript のコンパイラ オプションは、エラーが発生する前にキャッチするのに役立つ強力なツールです。
  • TypeScript の型システムを最大限に活用するには、常に 厳密モード を有効にしてください。
  • noImplicitAny および strictNullChecks オプションを使用して、型なし変数と null 値に関連するバグを検出します。

TypeScript の設定を適切に構成することで、よくある落とし穴を回避し、コードの信頼性を高め、保守を容易にし、バグを発生しにくくすることができます。

結論

TypeScript は、開発者がより安全で信頼性の高いコードを作成できる強力なツールですが、使い始めたばかりの場合は間違いを犯しやすいものです。型アサーションの誤用、any の過剰使用、null 可能性の無視、ジェネリックの誤解など、TypeScript の最も一般的な落とし穴について説明しました。これらの間違いは、予期しないバグやコードの保守が困難になる可能性があります。

これらの間違いを避けるための簡単なチェックリストは次のとおりです:

  • 型アサーションを誤用しないでください: 型について確実な場合にのみ使用してください。
  • 過度の使用は避けてください: 代わりに、不明なタイプまたはより具体的なタイプを使用してみてください。
  • any と不明の違いを理解します: 不明の方が安全であり、使用する前に型を確認する必要があります。
  • null と未定義を適切に処理します: オプションのチェーン、非 null アサーションを使用し、厳密な null チェックを有効にします。
  • 列挙型を過度に使用しないでください: 可能であれば、代わりに共用体型または文字列リテラルを使用してください。
  • ジェネリックを正しく使用します: 物事を複雑にしすぎず、正しい方法で適用する方法を理解してください。
  • TypeScript を正しく構成します: 問題を早期に発見するために厳密な設定を有効にします。

これらのよくある間違いを理解し、この記事で説明するベスト プラクティスに従うことで、よりクリーンで安全、そして保守しやすい TypeScript コードを作成できるようになります。

TypeScript の機能を活用して、バグを減らし、より信頼性の高いアプリケーションを作成するのに役立ててください。学習を続けて、コーディングを楽しんでください!

以上がTypeScript の罠: 開発者が犯しやすい間違いとその回避方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート