TypeScript ジェネリックパラメータのデフォルト型と新しい厳密なコンパイルオプション

TypeScript ジェネリックパラメータのデフォルト型と新しい厳密なコンパイルオプション

概要

TypeScript 2.3 では、ジェネリック パラメーターのデフォルト型を宣言するサポートが追加され、ジェネリック型の型パラメーターのデフォルト型を指定できるようになりました。

次に、ジェネリック パラメータのデフォルトを使用して、次の React コンポーネントを js (および jsX) から TypeScript (および TSX) に移行する方法を見てみましょう。

Greetingクラスはreact.Componentを拡張します。
  与える() {
    <span>Hello, {this.props.name}!</span> を返します。
  }
}

コンポーネントクラスの型定義を作成する

まず、Component クラスの型定義を作成しましょう。クラスベースの各 React コンポーネントには、props と state という 2 つのプロパティがあります。型定義の構造は、おおよそ次のようになります。

名前空間Reactを宣言する{
  クラスコンポーネント{
    小道具: 任意;
    状態: 任意;
  }
}

これはジェネリック型パラメータの内容とそのデフォルト値を示すため、非常に簡略化された例であることに注意してください。

これで、継承を通じて上で定義したコンポーネントを呼び出すことができます。

GreetingクラスはReact.Componentを拡張します。
  与える() {
    戻り値 <span>こんにちは、{this.props.name}!</span>
  }
}

次のようにしてコンポーネントのインスタンスを作成できます。

<Greeting name="world" />

上記のコンポーネントをレンダリングすると、次の HTML が生成されます。

<span>こんにちは、世界!</span>

いいですね、続けてください。

ジェネリック型を使用してPropsとStateを定義する

上記の例はコンパイルされて正常に実行されますが、コンポーネント型の定義はあまり正確ではありません。 props と state の型を any に設定しているため、TypeScript コンパイラーはあまり役に立ちません。

より具体的に、Props と State という 2 つの汎用型を使用して、props と state プロパティの構造を正確に記述できるようにします。

名前空間Reactを宣言する{
  クラス Component<Props, State> {
    小道具: 小道具;
    状態: 状態;
  }
}

次に、文字列型の名前プロパティを定義し、それを Props 型パラメータの型パラメータとして渡す GreetingProps 型を作成します。

GreetingProps と入力します。名前: 文字列 };

GreetingクラスはReact.Component<GreetingProps, any>を拡張します。
  与える() {
    <span>Hello, {this.props.name}!</span> を返します。
  }
}

1) GreetingPropsは型パラメータPropsの型パラメータです

2) 同様に、anyは型パラメータStateの型パラメータである。

これらの型を使用すると、コンポーネントの型チェックと自動ヒントが改善されます。

ただし、React.Component クラスを使用する場合は、両方のタイプを提供する必要があります。最初に開いたコード例では、型チェックが正しく行われなくなりました。

// エラー: ジェネリック型 Component<Props, State>
// 2 つの型パラメータが必要です。
GreetingクラスはReact.Componentを拡張します。
  与える() {
    <span>Hello, {this.props.name}!</span> を返します。
  }
}

GreetingProps のような型を指定したくない場合は、Props および State 型パラメータに any 型を指定してコードを修正できます。

GreetingクラスはReact.Component<any, any>を拡張します。
  与える() {
    <span>Hello, {this.props.name}!</span> を返します。
  }
}

この方法ではコンパイラーを渡すことが可能ですが、よりエレガントなアプローチとして、ジェネリック パラメーターのデフォルト タイプがあります。

汎用パラメータのデフォルトタイプ

TypeScript 2.3 以降では、各ジェネリック型パラメータにデフォルトの型を追加できます。次の例では、型パラメータが明示的に指定されていない場合、Props と State は両方とも any 型になります。

名前空間Reactを宣言する{
  クラス Component<Props = any, State = any> {
    小道具: 小道具;
    状態: 状態;
  }
}

これで、ジェネリック型を指定せずにコンパイラのチェックに合格できます。

GreetingクラスはReact.Componentを拡張します。
  与える() {
    <span>Hello, {this.props.name}!</span> を返します。
  }
}

もちろん、次のように、Props 型パラメータに型を明示的に指定し、デフォルトの any 型をオーバーライドすることもできます。

GreetingProps と入力します。名前: 文字列 };

GreetingクラスはReact.Component<GreetingProps, any>を拡張します。
  与える() {
    <span>Hello, {this.props.name}!</span> を返します。
  }
}

両方の型パラメータにデフォルトの型が追加されたため、これらはオプションとなり、Props に対してのみ明示的な型パラメータを指定できます。

GreetingProps と入力します。名前: 文字列 };

GreetingクラスはReact.Component<GreetingProps>を拡張します。
  与える() {
    <span>Hello, {this.props.name}!</span> を返します。
  }
}

型パラメータは 1 つだけ提供されることに注意してください。ただし、省略されたオプションの型パラメータの前の型を指定する必要があり、そうでない場合は省略できません。

その他の例

TypeScript 2.2 のミックスイン クラスに関する前回の記事では、最初に次の 2 つの型エイリアスを宣言しました。

型コンストラクタ<T> = new (...args: any[]) => T;
型コンストラクタブル = コンストラクタ<{}>;

構築可能な型は純粋に構文上の糖衣です。 Constructor<{}> 型を置き換えることができるため、ジェネリック型パラメータを毎回記述する必要がありません。ジェネリック パラメーターの既定値を使用すると、追加の構築可能な型を完全に削除し、{} を既定の型として設定できます。

型コンストラクタ<T = {}> = new (...args: any[]) => T;

構文は少し複雑ですが、生成されるコードはより簡潔です。良いですね。

新しい --strict メジャーコンパイルオプション

TypeScript 2.3 では、より厳密な型チェックに関連する他の多くのコンパイラ オプションを有効にする新しい --strict コンパイラ オプションが導入されました。

TypeScript によって追加された新しいチェックは、既存のプロジェクトとの非互換性を回避するために、通常はデフォルトでオフになっています。非互換性を回避することは良いことですが、この戦略の欠点の 1 つは、TypeScript のリリースごとに新しいオプションを明示的に追加する必要があるため、最大限の型安全性を実現するための構成がますます複雑になることです。 --strict コンパイル オプションを使用すると、最高レベルの型安全性を選択できます (コンパイラの新しいバージョンで強化された型チェック機能が追加されると、新しいエラーが報告される可能性があることに注意してください)。

新しい --strict コンパイラ オプションには、型チェック用の推奨構成オプションがいくつか含まれています。具体的には、--strict を指定することは、次のすべてのオプション (将来的にはさらに追加される可能性あり) を指定することと同じです。

  • --strictNullChecks
  • --暗黙的ではない
  • --暗黙的ではない
  • --常に厳密

TypeScript の将来のバージョンでは、このセットに追加の型チェック オプションが追加される可能性があります。つまり、プロジェクトで有効にする必要がある新しい厳密性オプションを取得するために、すべての TypeScript バージョンを監視する必要はありません。上記のオプション セットに新しいオプションが追加された場合、プロジェクトの TypeScript バージョンをアップグレードすると、それらのオプションが自動的にアクティブ化されます。

--strict コンパイラ オプションは、上記のコンパイラ オプションのデフォルト値を設定します。つまり、これらのオプションも個別に制御できます。例えば:

--strict --noImplicitThis

または、tsconfig.json ファイルで指定します。

{
  "厳密": 真、
  "alwaysStrict": 偽
}

これにより、--noImplicitThis コンパイラ オプションを除くすべての厳密なチェック オプションが有効になります。このアプローチにより、明示的にリストされた一部の項目を除くすべての項目に対して厳密なチェックを表現できます。つまり、最高レベルの型安全性で、デフォルトでいくつかのチェックを除外することが可能になりました。

--init 出力の改善

デフォルトの --strict 設定に加えて、 tsc --init の出力が改善されました。 tsc --init によってデフォルトで生成される tsconfig.json ファイルには、現在、説明とともにコメントアウトされた、よく使用されるコンパイラ オプションがいくつか含まれています。関連するオプションのコメントを解除すると、期待どおりの結果が得られます。新しい出力により、新しいプロジェクトの構成が簡素化され、プロジェクトの拡大に​​合わせて構成ファイルの読みやすさが向上することを期待しています。

tsc --init コンパイラはビルド用の構成ファイルを作成できます。

$ tsc --init

メッセージ TS6071: tsconfig.json ファイルが正常に作成されました。

このコマンドを実行すると、現在の作業ディレクトリに tsconfig.json ファイルが生成されます。生成される構成は次のとおりです。

{
  "コンパイラオプション": {
    /* 基本オプション */
    "target": "es5", /* ECMAScript ターゲット バージョンを指定します: 'ES3' (既定値)、'ES5'、'ES2015'、'ES2016'、'ES2017'、または 'ESNEXT'。 */
    "module": "commonjs", /* モジュール コード生成を指定します: 'commonjs'、'amd'、'system'、'umd'、または 'es2015'。 */
    // "lib": [], /* コンパイルに含めるライブラリファイルを指定します: */
    // "allowJs": true, /* JavaScript ファイルのコンパイルを許可します。 */
    // "checkJs": true, /* .js ファイル内のエラーを報告します。 */
    // "jsx": "preserve", /* JSX コード生成を指定します: 'preserve'、'react-native'、または 'react'。 */
    // "declaration": true, /* 対応する '.d.ts' ファイルを生成します。 */
    // "sourceMap": true, /* 対応する '.map' ファイルを生成します。 */
    // "outFile": "./", /* 出力を連結して 1 つのファイルに出力します。 */
    // "outDir": "./", /* 出力構造をディレクトリにリダイレクトします。 */
    // "rootDir": "./", /* 入力ファイルのルートディレクトリを指定します。--outDir を使用して出力ディレクトリ構造を制御するために使用します。 */
    // "removeComments": true, /* 出力にコメントを出力しません。 */
    // "noEmit": true, /* 出力を出力しません。 */
    // "importHelpers": true, /* 'tslib' からエミット ヘルパーをインポートします。 */
    // "downlevelIteration": true, /* 'ES5' または 'ES3' をターゲットとする場合、'for-of'、スプレッド、および構造化分解における反復可能オブジェクトの完全なサポートを提供します。 */
    // "isolatedModules": true, /* 各ファイルを個別のモジュールとしてトランスパイルします ('ts.transpileModule' と同様)。 */

    /* 厳密な型チェックオプション */
    "strict": true /* すべての厳密な型チェックオプションを有効にします。 */
    // "noImplicitAny": true, /* 暗黙の 'any' 型を含む式と宣言でエラーを発生させます。 */
    // "strictNullChecks": true, /* 厳密な null チェックを有効にします。 */
    // "noImplicitThis": true, /* 暗黙の 'any' 型を持つ 'this' 式でエラーを発生させます。 */
    // "alwaysStrict": true, /* 厳密モードで解析し、各ソース ファイルに対して "use strict" を出力します。 */

    /* 追加のチェック */
    // "noUnusedLocals": true, /* 未使用のローカルのエラーを報告します。 */
    // "noUnusedParameters": true, /* 未使用のパラメータに関するエラーを報告します。 */
    // "noImplicitReturns": true, /* 関数内のすべてのコードパスが値を返さない場合はエラーを報告します。 */
    // "noFallthroughCasesInSwitch": true, /* switch ステートメントのフォールスルー ケースのエラーを報告します。 */

    /* モジュール解決オプション */
    // "moduleResolution": "node", /* モジュール解決戦略を指定します: 'node' (Node.js) または 'classic' (TypeScript 1.6 以前)。 */
    // "baseUrl": "./", /* 絶対値でないモジュール名を解決するためのベースディレクトリ。 */
    // "paths": {}, /* 'baseUrl' を基準とした参照場所にインポートを再マップする一連のエントリ。 */
    // "rootDirs": [], /* 実行時にプロジェクトの構造を表す結合されたコンテンツを持つルート フォルダーのリスト。 */
    // "typeRoots": [], /* 型定義を含めるフォルダーのリスト。 */
    // "types": [], /* コンパイルに含める型宣言ファイル。 */
    // "allowSyntheticDefaultImports": true, /* デフォルトエクスポートのないモジュールからのデフォルトインポートを許可します。これはコードの出力には影響せず、型チェックのみに影響します。 */

    /* ソースマップオプション */
    // "sourceRoot": "./", /* デバッガーがソースの場所ではなく TypeScript ファイルを検索する場所を指定します。 */
    // "mapRoot": "./", /* 生成された場所ではなく、デバッガーがマップ ファイルを検索する場所を指定します。 */
    // "inlineSourceMap": true, /* 別のファイルを作成する代わりに、ソースマップを含む単一のファイルを出力します。 */
    // "inlineSources": true, /* ソースマップと一緒にソースを 1 つのファイル内に出力します。'--inlineSourceMap' または '--sourceMap' を設定する必要があります。 */

    /* 実験的なオプション */
    // "experimentalDecorators": true, /* ES7 デコレータの実験的なサポートを有効にします。 */
    // "emitDecoratorMetadata": true, /* デコレータの型メタデータの出力の実験的なサポートを有効にします。 */
  }
}

--strict はデフォルトで有効になっていることに注意してください。つまり、新しい TypeScript プロジェクトを開始すると、自動的にデフォルト モードになります。

--checkJS オプションを使用した .js ファイルのエラー

--allowJs を指定しても、TypeScript コンパイラはデフォルトでは .js ファイル内のエラーを報告しません。 TypeScript 2.3 では、--checkJs オプションを使用して .js ファイル内の型チェック エラーも報告できます。

// @ts-nocheck コメントを追加することで、特定のファイルのチェックをスキップできます。逆に、// @ts-check コメントを追加することで、--checkJs コンパイル オプションを設定せずに、一部の .js ファイルのみをチェックするように選択できます。特定の行の前に // @ts-ignore を追加することで、その行のエラーを無視することもできます。

.js ファイルは引き続き、標準の ECMAScript 機能のみが存在することを確認するためにチェックされ、型注釈は .ts ファイルでのみ許可され、.js ファイルではエラーとしてフラグが付けられます。 JSDoc コメントを使用すると、JS コードにいくつかの型情報を追加できます。

以上がTypeScriptジェネリックパラメータのデフォルト型と新しい厳密なコンパイルオプションの詳細です。TypeScriptの詳細については、123WORDPRESS.COMの他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • ReactプロジェクトでのTypeScriptの実装
  • React+tsは二次リンク効果を実現します
  • React プロジェクトにおける TypeScript の使用の概要
  • React でカレンダー コンポーネントを構築するためのステップ バイ ステップ ガイド
  • フロントエンド React Nextjs での TS 型フィルタリングの実用的なヒント

<<:  MySQL 5.7 で my.ini ファイルが見つからない場合の解決策

>>:  CentOS はローカル yum ソースを使用して LAMP 環境を構築するグラフィック チュートリアル

推薦する

17 個の JavaScript ワンライナー

目次1. DOMとBOM関連1. 要素にフォーカスがあるかどうかを確認する2. 要素の兄弟ノードをす...

MySQL 8.0.15 で MGR シングル マスターと複数スレーブを構成する方法

1. はじめにMySQL グループ レプリケーション (略して MGR) は文字通り MySQL グ...

Linux 仮想メモリ設定のチュートリアルと実践

仮想メモリとは何ですか?まずはWikipediaからの紹介文をそのまま引用します。仮想メモリは、コン...

MySQL 5.7.19 のインストールと設定方法のグラフィック チュートリアル (win10)

以下に記録されているように、WIN10システムにMYSQLをダウンロードしてインストールするための詳...

Reactホームページの読み込みが遅い問題のパフォーマンス最適化事例の詳細な説明

しばらくReactを勉強した後、実践してみたいと思います。そこで、個人のブログのウェブサイトを再構築...

Vue ルーターにパラメータを渡すときにページを更新するとパラメータが失われる問題に対処する方法

目次概要方法1: params経由でパラメータを渡す方法2: クエリを通じてパラメータを渡す方法3:...

Linux システムで Vim を使用してリモート ファイルを読み書きするコマンドの詳細な説明

vim の動作モードを設定する (一時的) :set (モード情報) :set nu — 行番号を表...

Vueプロジェクトがグラフィック検証コードを実装

この記事の例では、グラフィック検証コードを実装するためのVueプロジェクトの具体的なコードを参考まで...

Ubuntu 19でdockerソースをインストールできない問題を共有する

主要な Web サイトと個人的な習慣に従って、Docker ソースを追加するには次の方法を使用します...

CSS を使用してプログレスバーと順序プログレスバーを実装する例

この半月、期末試験の準備にかなりのエネルギーを費やしました。今日はしっかり復習するべきだったのですが...

MySQL 5.7.17 圧縮パッケージのインストール不要の構成プロセス図

MySQL データベース管理ソフトウェアには、エンタープライズ エディションとコミュニティ エディシ...

KTLツールはMySQLからMySQLへのデータの同期方法を実現します

ktl ツールを使用して、mysql から mysql にデータを同期します。 1. 新しいジョブス...

Node8 における AsyncHooks 非同期ライフサイクル

Async Hooks は Node8 の新機能です。NodeJs の非同期リソースのライフサイクル...

HTML の marquee 属性の詳細な説明

このタグはHTML3.2の一部ではなく、MSIE3以降のカーネルでのみサポートされているため、IEカ...

axiosのシンプルなカプセル化と使用例コード

序文最近、プロジェクトを構築しているときに、リクエストのカプセル化について考え、どのようにカプセル化...