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 のヒント

推薦する

VUE+Express+MongoDBのフロントエンドとバックエンドの分離によるノートウォールの実現

付箋紙の壁シリーズを実現しようと思っています。シンプルなものはシンプル、複雑なものは多機能です。開発...

フロントエンドエンジニアが作ったクールなインタラクティブウェブサイトを推薦します

ウェブサイトリンク: http://strml.net/サミュエル・リード著ヒント: 昨日、Mome...

シェルスクリプトはNginxのaccess.logのPVを定期的にカウントし、APIに送信してデータベースに保存します。

1. PVとIPの統計一日のPV(ページビュー)をカウントする cat access.log | ...

TypeScript をインストール、使用、自動コンパイルする方法に関するチュートリアル

1. TypeScriptの紹介前回の記事ではTypeScriptのインストール、使い方、自動コンパ...

JavaScript の数値および数学オブジェクトの概要

目次1. JavaScript における数値2. Javascript の Math オブジェクト1...

MySQL 5.7 のスロークエリログの時間がシステム時間より 8 時間遅れている理由の詳細な説明

遅いクエリをチェックすると、時間が正しくなく、システム時間とちょうど 8 時間異なっていることがわか...

CSSでフレックス配置を表示する(レイアウトツール)

display: flex レイアウトに関しては、深く理解している人もいますし、私も他の人の作業か...

mysql5.7.18 解凍バージョンで mysql サービスを起動します

mysql5.7.18の解凍版はmysqlサービスを起動します。具体的な内容は以下のとおりです。 1...

CSS3 は下部に固定されたフッターを実装します (ページの高さに関係なく常に下部にあります)

序文フッター領域を下部に固定します。ページの高さや幅に関係なく、モバイル メニューと同様に、フッター...

Linux での chmod コマンドの使用方法の詳細な説明

chmod コマンド構文chmod コマンドを使用する場合の正しい構文は次のとおりです。 chmod...

Docker Enterprise Edition を使用して独自のプライベート レジストリ サーバーを構築する

Docker は本当に素晴らしいです。特に、仮想マシンを使用する場合に比べて、Docker イメージ...

MySQLのジョイントインデックス機能の分析と使用例

この記事では、例を使用して、MySQL 共同インデックスの機能と使用方法を説明します。ご参考までに、...

Dockerでrabbitmqをデプロイする際に発生した2つの問題

1. 背景DockerでRabbitMQをデプロイする際に、次の2つの問題が発生します。問題1: ス...

mysql5.6.8 ソースコードのインストールプロセス

カーネル: [root@opop ~]# cat /etc/centos-release CentO...

ボックスモデルのサイズの詳細な説明は、パディング、マージン、境界の値によって異なります。

ボックス モデルは、要素ボックスの幅と高さ、パディング、境界線、余白のサイズを指定します。境界線の内...