TypeScript Deep Dive 日本語版
  • TypeScript Deep Dive 日本語版
  • TypeScript入門 & 環境構築
    • なぜTypeScriptを使うのか?
  • JavaScript
    • 等価演算子の同一性
    • リファレンス
    • nullとundefined
    • this
    • クロージャ
    • Number型
    • Truthy
  • モダンなJavaScriptの機能
    • クラス
      • Classes Emit
    • アロー関数
    • 残余引数(Restパラメータ)
    • let
    • const
    • 分割代入
    • スプレッド演算子
    • for...of
    • Iterator
    • テンプレートリテラル
    • Promise
    • ジェネレータ
    • async await
  • プロジェクトの環境設定
    • コンパイルコンテキスト
      • tsconfig.json
      • コンパイル対象ファイルの設定
    • 宣言空間
    • ファイルモジュール
      • ファイルモジュールの詳細
      • global.d.ts
    • 名前空間
    • 動的インポート
  • Node.js & TypeScriptのプロジェクト作成
  • React & TypeScriptのプロジェクト作成
  • TypeScriptの型システム
    • JavaScriptからの移行ガイド
    • @types パッケージ (DefinitelyTyped)
    • アンビエント宣言(declare)
      • 型定義ファイル
      • グローバル変数の宣言
    • インターフェース
    • Enum
    • lib.d.ts
    • 関数の型
    • 呼び出し可能オブジェクト
    • Type Assertion(型アサーション)
    • Freshness
    • 型ガード
    • リテラル型
    • Readonly
    • ジェネリック型
    • 型推論
    • 型の互換性
    • never
    • 判別可能なUnion型
    • Index signature(インデックス型)
    • 型の移動
    • 例外のハンドリング
    • ミックスイン
  • JSX
    • React
    • React以外のJSX
  • オプション
    • noImplicitAny
    • strictNullChecks
  • TypeScriptのエラー
    • エラーの理解
    • 一般的なエラー
  • NPM
  • テスト
    • Jest
    • Cypress
  • ツール
    • Prettier
    • Husky
    • Changelog
  • その他のヒント
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Bind is Bad
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • スタイルガイド(コーディング規約)
  • TypeScriptコンパイラの内側
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
GitBook提供
このページ内
  • エラーサブタイプ
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError
  • 常にエラーを使用する
  • あなたはエラーをスローする必要はありません
  • 例外的なケース
  • どこに投げられるのか不明
  • 優雅なハンドリングを困難にする
  • 型システムでうまく表現されていない

役に立ちましたか?

  1. TypeScriptの型システム

例外のハンドリング

JavaScriptには、例外のために使用できるErrorクラスがあります。あなたはthrowキーワードでエラーを投げます。あなたはtry/catchブロックの対でそれを捕まえることができます。

try {
  throw new Error('Something bad happened');
}
catch(e) {
  console.log(e);
}

エラーサブタイプ

ビルトインされたErrorクラスのほかに、JavaScriptランタイムが投げることができるErrorを継承するいくつかの組み込みエラークラスがあります:

RangeError

数値変数またはパラメータが有効な範囲外にあるときに発生するエラーを表すインスタンスを作成します。

// Call console with too many arguments
console.log.apply(console, new Array(1000000000)); // RangeError: Invalid array length

ReferenceError

参照されたのが無効な参照だった場合に発生するエラーを表すインスタンスを作成します。例えば

'use strict';
console.log(notValidVar); // ReferenceError: notValidVar is not defined

SyntaxError

有効でないJavaScriptを解析する際に発生する構文エラーを表すインスタンスを作成します。

1***3; // SyntaxError: Unexpected token *

TypeError

変数またはパラメータが有効な型でないときに発生するエラーを表すインスタンスを作成します。

('1.2').toPrecision(1); // TypeError: '1.2'.toPrecision is not a function

URIError

encodeURI()または decodeURI()に無効なパラメータが渡されたときに発生するエラーを表すインスタンスを生成します。

decodeURI('%'); // URIError: URI malformed

常にエラーを使用する

初心者のJavaScriptデベロッパーは、たまに生の文字列のみをエラーとして投げます。

try {
  throw 'Something bad happened';
}
catch(e) {
  console.log(e);
}

これはしないでください。Errorオブジェクトの基本的な利点は、stackプロパティを使ってビルドされた場所を自動的に追跡することです。

生の文字列は非常に苦しいデバッグ経験をもたらし、ログからのエラー分析を複雑にします。

あなたはエラーをスローする必要はありません

Errorオブジェクトを渡すことは大丈夫です。これは、Node.jsのコールバックスタイルコードでは、最初の引数をエラーオブジェクトとしてコールバックを受け取ります。

function myFunction (callback: (e?: Error)) {
  doSomethingAsync(function () {
    if (somethingWrong) {
      callback(new Error('This is my error'))
    } else {
      callback();
    }
  });
}

例外的なケース

「例外は例外的でなければならない」は、コンピュータサイエンスの一般的な言葉です。これがJavaScript(およびTypeScript)にも当てはまる理由はいくつかあります。

どこに投げられるのか不明

次のコードを考えてみましょう。

try {
  const foo = runTask1();
  const bar = runTask2();
}
catch(e) {
  console.log('Error:', e);
}

次の開発者は、どの関数がエラーを投げるかわかりません。コードをレビューしている人は、task1/task2のコードとそれが呼び出す可能性のある他の関数を読み取ることなく知ることができません。

優雅なハンドリングを困難にする

スローする可能性のあるものの周りを明示的にキャッチして優雅にしようとすることができます:

try {
  const foo = runTask1();
}
catch(e) {
  console.log('Error:', e);
}
try {
  const bar = runTask2();
}
catch(e) {
  console.log('Error:', e);
}

しかし、最初のタスクから2番目のタスクに物事を渡す必要がある場合、コードは乱雑になります。(fooのミューテションにlet が必要になる + 明示的に型をアノテートしなければならなくなることに注意してください。これは、runTask1の戻り値から型を推測できないためです) :

let foo: number; // Notice use of `let` and explicit type annotation
try {
  foo = runTask1();
}
catch(e) {
  console.log('Error:', e);
}
try {
  const bar = runTask2(foo);
}
catch(e) {
  console.log('Error:', e);
}

型システムでうまく表現されていない

次の関数を考えてみましょう。

function validate(value: number) {
  if (value < 0 || value > 100) throw new Error('Invalid value');
}

このような場合にErrorを使うのは、validate関数の型定義((value:number) => void)で表現されていないので、悪い考えです。代わりに、検証メソッドを作成するためのより良い方法は次のとおりです。

function validate(value: number): {error?: string} {
  if (value < 0 || value > 100) return {error:'Invalid value'};
}

そして今、型システムで表現されています。

非常に一般的な(シンプル/キャッチオールなど)の方法でエラーを処理しない限り、エラーをスローしないでください。

前へ型の移動次へミックスイン

最終更新 2 年前

役に立ちましたか?