TypeScript で時間を費やした場所の概要

TypeScript で時間を費やした場所の概要

TS で時間を過ごした場所をいくつか記録します。

(まず、文句を言わせてください。stackoverflow には本当に何でも揃っていますが、Baidu は本当に役に立たないです)

ピット

「a」を「b」として解釈するなど、as アサーションの互換性の誤解ではエラーは報告されません。

インターフェースと型の間の動作に一貫性がありません (最初に遭遇したとき、間違った型を書いたと思って混乱しました):

タイプ タイプ = {
  キー: "値"
}
インターフェース インターフェース {
  キー: "値"
}

型は違いがないように見えますが、両方とも true = Type extends Interface ? Type extends Interface ? true : false : false

タイプ ピットポイント = {
  [キー: 文字列]: ピットポイント} | 文字列

型 test<T> = T は pitfall を拡張しますか? true : false
タイプ これは true です = テスト <タイプ>
タイプ これは false です = テスト <インターフェース>

この穴は意図的に残されたという公式の説明が GitHub にあります。インターフェースが拡張可能(同じ名前は自動的にマージされる)なので、検出が不便だと言われています。

ジェネリックを使用して関数オーバーロードを実装する場合、ジェネリックには特定の制約がないため、関数の実装では強制アサーションとして使用する必要があることがよくあります。

//これで終わりです。次のコードを実際にテストするのは面倒です 🙃

//fns は関数インデックス テーブル、TFns はインデックス テーブルの const 型です。関数のオーバーロードに失敗しました <T extends keyof TFns>(fn:T, params: Parameters<fns[T]>){
    fns[fn](...params) //実装では、共用体型は縮小されないので、エラーが報告されます //エラーは「メソッド 1 のパラメータをメソッド 2 に渡すことができません」のようなものになります}
//しかし、外部で使用する場合、型のセマンティクスが満たされているかどうかは関係ありません

スプレッド演算子は直感的ではありません。 [...string[], number] は直感的に使用できます (配列の末尾に数値要素が必要) が、[...string[], null, ...object[], number] は直感的ではなく、エラーも報告されません。 ts の新しいバージョンでは、連続分解を禁止するルールが追加されているため、このタイプの記述は許可されません。

実はここに解決策があるのですが、記述された型は単純に読めないものなので(数十行、型 if 判断として機能する多数の extends を含む)、投稿しません。コードは以下のとおりです。

// 必要な型: [...number[], "middle-element", ...boolean[]] 
//上記は無効です。これは、次の型コードが何のために使用されるかを示しているだけです(上記の型制約を実装するため)

type Elem = number | boolean | "中間の要素";

型 Last<T extends any[]> = T extends [infer _]
  ? 一度もない
  : T は [..._ を推論し、Tl を推論する] を拡張します
  ? テル
  : 一度もない

型HandleEmpty<T extends any[], Data> = T['length'] extends 0 ? never : Data

型Validation<Params extends any[], Cache extends Elem[] = []> =
  パラメータは[]を拡張します
  ? キャッシュ['length']は0を拡張します
  ? 一度もない
  : キャッシュ
  : Params は [Fst を推論し、...Rest を推論] を拡張します
  ? キャッシュは [] を拡張します
  ? Fstは数値を拡張します
  ? HandleEmpty<Rest、Validation<Rest、[...Cache、Fst]>>
  : 一度もない
  : Fstは数値を拡張します
  ? Last<Cache> は数値を拡張します
  ? HandleEmpty<Rest、Validation<Rest、[...Cache、Fst]>>
  : 一度もない
  : Fst は「中間要素」を拡張します
  ? Last<Cache> は数値を拡張します
  ? HandleEmpty<Rest、Validation<Rest、[...Cache、Fst]>>
  : 一度もない
  : 「中間要素」はCache[番号]を拡張します
  ? Fstはブール値を拡張します
  ? 検証<Rest、[...Cache、Fst]>
  : 一度もない
  : 一度もない
  : 一度もない

型 IsNever<T> = [T] は [never] を拡張します ? true : false;

機能チェック<
  ParamsはElem[]を拡張します。
  IsValid は Validation<Params> を拡張します。
>(...arr: IsNever<IsValid> は true を拡張しますか? [never] : [...Params]) {
  リターン
}

const normal = check(1, '中間要素', false)
const error = check(false, "中間要素", 2)

高度な操作

オブジェクト名の再マッピング:

//{ "new-a":任意; "new-b":任意 }
タイプ リマップ = {
    [K in "a" | "b" を `new-${K}` として]: 任意
}

ユニオン型の分割: infer キーワードを使用してユニオン型を分割できます。

//"a1"|"b2"
型分割が正常に完了しました <_Keys = keyof { a: 1, b: 2 }> = _Keys は infer K を拡張しますか?
    `${Extract<K, 文字列>}${{ a: 1, b: 2 }[Extract<K, _Keys>]}`
    : 一度もない

// 注: (ts4.4.4 時点) 直接 `keyof Obj extends infer K` はユニオン型を分割できません。理由は不明です (確認するのが面倒です 😁)。
//結果は「a1」|「a2」|「b1」|「b2」
型の分割に失敗しました = keyof { a: 1, b: 2 } は infer K を拡張しますか?
    `${Extract<K, 文字列>}${{ a: 1, b: 2 }[Extract<K, "a" | "b">]}`
    : 一度もない

タプル型:

  • 実際の(非型)パラメータは、as const を使用してタプル型として明示的に宣言する必要がある場合があります。
  • タプル型は、tuple["length"] を通じて数値ではなく正確な長さを取得できます。
  • ジェネリック パラメーターを通じてタプル型を使用する場合、通常の不定長配列型として解析されるのを避けるために、[]| を追加して、タプルを []|any[] として拡張するように記述する必要がある場合があります。

再帰型: 配列型の再帰を実装するには、...infer More を使用します。

型Converter<T> = Tは文字列を拡張しますか? "str" ​​: null
//[文字列、数値、文字列]として入力され、["str",null,"str"]として出力されます
型の再帰<
        入力ソースはany[]を拡張します。
        内部型キャッシュはany[] = []を拡張します。
    > = 入力ソースは [any、...残りの要素を推測] を拡張しますか?
        再帰 <残りの要素、[...内部型キャッシュ、コンバーター <入力ソース [0]>]>
        : 入力ソース

その他

  • & は、型に対して extends の代わりに使用できます。インターフェースには、同じ名前の型をマージできることを除いて、他の違いはありません。
  • ts には豊富な組み込み型があります。以下にいくつか例を示します。
    • ReturnType<関数型>は、関数型の戻り値の型を取得します。
    • <文字列> を大文字にせず、入力文字列タイプの最初の文字を小文字に固定します (他のオプションには、最初の文字を大文字にする、すべて小文字にする、すべて大文字にするなどがあります)。

初心者の方は公式サイトにアクセスしてドキュメントを読むことをお勧めします。

ts に慣れてきたら、バージョン アップデートによってもたらされる新しい機能 (ゲームプレイ) に注目してください。

要約する

TypeScript で時間を費やした場所をまとめたこの記事はこれで終わりです。TypeScript で時間を費やした場所に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。

<<:  CSSの複数条件の書き方の詳細説明:

>>:  デザイン理論: コンテンツプレゼンテーションのための 10 のヒント

推薦する

Dockerfile を使用して Node.js サービスをデプロイする方法

Dockerfileを初期化するプロジェクトの名前が express であると仮定して、expres...

仮想マシンクローン Linux centos6.5 システム ネットワーク カード構成グラフィック チュートリアル

Linux システムに触れたばかりの初心者として、VMware 仮想マシンに CentOS6.5 シ...

簡単な手順で純粋な CSS3 で 3D 反転効果を実現

フロントエンド開発者の必須科目であるCSS3は、多くの基本的なアニメーション効果を実現するのに役立ち...

Oracle10パーティションとMySQLパーティションの違いの詳細な説明

一般的に使用される Oracle10g パーティションは、範囲 (範囲パーティション)、リスト (リ...

優れたウェブワイヤーフレーム設計・制作ツール13選を紹介

プロジェクトの作業を開始するときは、ワイヤーフレームを使用してアイデアをスケッチすることが重要です。...

MySQLのunion allとunionの違いを簡単に理解する

Union は、重複行を除外し、デフォルトのソートを実行する、データに対する結合操作です。Union...

CSS 線形グラデーション凹型長方形遷移効果の実装

この記事では、線形グラデーションの凹四角形の遷移効果の難しさやアイデアについて説明します。主に、凹四...

SQLはLeetCodeを実装します(180.連続した数字)

[LeetCode] 180. 連続した数字少なくとも 3 回連続して出現するすべての数字を検索す...

モバイルフロントエンド適応ソリューション(概要)

ネットで検索してみたところ、多くの面接でモバイル適応方法について質問されることが分かりました。最近い...

Dockerを使用してクローンリポジトリを使用してGitイメージを構築する

概要私は 1 年以上 Docker を使用しています。最近、サービスをすばやくオーケストレーションし...

CSSを使用してアダプティブスクエアを実装する方法の例

伝統的な方法は、正方形を固定形式で書くことです。長さ=幅を直接書き、次のように固定値を書きます。 。...

vue-admin-template 動的ルーティング実装例

ログインを提供し、ユーザー情報データインターフェースを取得するapi/user.js内 '@...

MySQL 8.0.19 インストール詳細チュートリアル (Windows 64 ビット)

目次MySQLを初期化するMySQL サービスをインストール + MySQL サービスを開始MySQ...

Reactにおけるコンポーネント通信の詳細な説明

目次親コンポーネントは子コンポーネントと通信します子コンポーネントは親コンポーネントと通信しますコン...

Linux ホスト上で複数の MySQL データベースを起動する方法

今日は、Linux ホスト上で 4 つの MySQL データベースを起動する方法について説明します。...