序文長い間Typescriptを使ってきましたが、まだ使いこなせていない気がします。 TypeScript の多くの機能が使用されていないため、以前に書いたコードは any でいっぱいになり、多くのバグが発生しやすくなり、TypeScript の真の「型」のパワーが発揮されません。この記事では、今後 TypeScript を使用する際に役立つ、TypeScript の使用に関するヒントをいくつかまとめています。 では、これ以上長々とせずに、すぐにコードを見てみましょう。 関数のオーバーロードユーザーパラメータを渡す場合はフラグを渡さないでください。パラパラメータを渡す場合はフラグを渡します。次のように記述できます: インターフェース ユーザー { 名前: 文字列; 年齢: 番号; } 定数ユーザー = { 名前: 'ジャック', 年齢: 123 }; クラス SomeClass { パブリックテスト(para: User): number; パブリックテスト(para: number, flag: boolean): number; パブリックテスト(para: ユーザー | 数値、フラグ?: ブール値): 数値 { // 特定の実装 return 1; } } const someClass = 新しい SomeClass(); // わかりました someClass.test(ユーザー); someClass.test(123, false); // エラー // someClass.test(123); // 'number' 型の引数は 'User' 型のパラメータに割り当てることができません。 // someClass.test(user, false); // '{ name: string; age: number; }' 型の引数は 'number' 型のパラメータに割り当てることができません。 マッピングタイプマッピング タイプを理解する前に、keyof、never、typeof、in を理解する必要があります。 keyof: keyofはインターフェースのキーを取得します インターフェースポイント{ x: 数値; y: 数値; } // タイプキー = "x" | "y" タイプ keys = keyof Point; never: 決して存在しない値のタイプ 公式の説明:
// 例: 包括的なコンパイル時チェックを実行する type Foo = string | number; 関数 controlFlowAnalysisWithNever(foo: Foo) { if (typeof foo === "文字列") { // ここで foo は文字列型に絞り込まれます } else if (typeof foo === "number") { // ここで foo は number 型に絞り込まれます } else { // foo はここには決して存在しません const チェック: never = foo; } } 対応する実装のない新しいユニオン型の追加を回避するには、 never を使用します。目的は、完全に型安全なコードを記述することです。 typeof: 値の型を取得する 定数a: 数値 = 3 // 次と同等: const b: number = 4 定数 b: 型 a = 4 in: オブジェクトにプロパティが存在するかどうかを確認します インターフェースA { x: 数値; } インターフェースB { y: 文字列; } 関数doStuff(q: A | B) { ('x'がqにある場合){ // 質問: A } それ以外 { // 質問: B } } マッピング タイプとは、あるタイプを別のタイプにマッピングすることです。簡単に言うと、新しいタイプは古いタイプの各属性を同じ形式で変換します。 部分的、読み取り専用、Null 可能、必須
型 Partial<T> = { [TのキーのP]?: T[P]; } 型 Readonly<T> = { 読み取り専用[P in keyof T]: T[P]; } Nullable<T>型 = { [T のキーの P]: T[P] | null } 型 Required<T> = { [TのキーのP]-?: T[P] } インターフェース Person { 名前: 文字列; 年齢: 番号; } PersonPartial と入力します。 PersonReadonly = Readonly<Person> と入力します。 PersonNullable 型 = Nullable<Person>; タイプ PersonPartial = { 名前?: 文字列 | 未定義; 年齢?: 数値 | 未定義; } タイプ PersonReadonly = { 読み取り専用の名前: 文字列; 読み取り専用 age: 数値; } タイプ PersonNullable = { 名前: 文字列 | null; 年齢: 数値 | null; } インターフェースProps{ a?: 数値; b?: 文字列; } 定数obj: Props = { a: 5 }; const obj2: 必須<Props> = { a: 5 }; // プロパティ 'b' はタイプ '{ a: number; }' では欠落していますが、タイプ 'Required<Props>' では必須です。 選択、記録
型 Pick<T, K は keyof T> を拡張します = { [KのP]:T[P]; } 型 Record<K extends keyof any, T> = { [K 内の P]: T; } インターフェースTodo { タイトル: 文字列; 説明: 文字列; 完了: ブール値; } type TodoPreview = Pick<Todo, "title" | "completed">; 定数todo: TodoPreview = { タイトル: 「クリーンルーム」 完了: 偽、 }; todo; // = const todo: TodoPreview インターフェース PageInfo { タイトル: 文字列; } Page = "home" | "about" | "contact" と入力します。 const nav: レコード<ページ、ページ情報> = { について: { タイトル: "title1" }, 連絡先: { タイトル: "title2" }, ホーム: { タイトル: "title3" }, }; nav.about; // = const nav: レコード 除外、省略
型 Exclude<T, U> = T は U を拡張しますか? 決して: T タイプ Omit = Pick<T, Exclude<keyof T, K>> // 次と同等: type A = 'a' タイプ A = 除外<'x' | 'a', 'x' | 'y' | 'z'> インターフェースTodo { タイトル: 文字列; 説明: 文字列; 完了: ブール値; } type TodoPreview = Omit<Todo, "description">; 定数todo: TodoPreview = { タイトル: "a", 完了: 偽、 }; 戻り値の種類戻り値の型を取得します。通常は関数です。 型 ReturnType<T extends (...args: any) => any> = T は (...args: any) を拡張します => R ? R : any を推論します。 関数 f1() を宣言します: { a: 数値; b: 文字列 }; 型 T1 = ReturnType<typeof f1>; // タイプ T1 = { // a: 数値; // b: 文字列; // } マッピング タイプは他にもたくさんあります。ユーティリティ タイプ リファレンスを参照してください。 型アサーション型アサーションは、値の詳細な型を TypeScript に明示的に伝えるために使用されます。適切に使用することで作業負荷を軽減できます。 たとえば、変数には初期値がありませんが、その型情報はわかっています(バックエンドから返される場合があります)。型情報を正しく推測して正常に実行する方法はありますか?オンラインで推奨される方法の 1 つは、初期値を設定し、typeof を使用して型を取得することです (他の場所でも使用できます)。この問題を解決するには、型アサーションを使用することもできます。 インターフェース ユーザー { 名前: 文字列; 年齢: 番号; } デフォルトクラス someClass をエクスポートします。 プライベートユーザー = {} をユーザーとして; } 列挙する列挙型は数値型と文字列型に分かれており、数値列挙はフラグとして使用できます。 列挙型動物フラグ{ なし = 0、 爪あり = 1 << 0, カンフライ = 1 << 1、 HasClawsOrCanFly = HasClaws | CanFly } インターフェース動物{ フラグ: AnimalFlags; [キー: 文字列]: 任意; } 関数 printAnimalAbilities(animal: Animal) { var animalFlags = animal.flags; 動物フラグと動物フラグ.爪がある場合 console.log('動物には爪があります'); } 動物フラグと動物フラグ.CanFly の場合 { console.log('動物は飛べる'); } 動物フラグ == 動物フラグ.None の場合 { console.log('何もない'); } } var animal = { flags: AnimalFlags.None }; printAnimalAbilities(animal); // なし animal.flags |= AnimalFlags.HasClaws; printAnimalAbilities(animal); // 動物には爪がある animal.flags &= ~AnimalFlags.HasClaws; printAnimalAbilities(animal); // なし animal.flags |= AnimalFlags.HasClaws | AnimalFlags.CanFly; printAnimalAbilities(animal); // 動物には爪があり、動物は飛べます
これはあまり一般的には使用されないかもしれません。TypeScript のソース コードにも、型に関する同様のコードが見られます。 文字列型の列挙では定数を保持できます。 定数列挙型TODO_STATUS { TODO = 'TODO'、 完了 = '完了'、 行う = '行う' } 関数 todos (ステータス: TODO_STATUS): Todo[]; やること(TODO_STATUS.TODO) タプル既知の数と型の要素の配列を表します。同じ型である必要はありません。 let x: [文字列, 数値]; x = ['こんにちは', 10]; 複数のリクエストを行う場合は、以下を適用できます。 const requestList: any[] = [http.get<A>('http://some.1')]; // any[]型に設定 if (flag) { リクエストリスト[1] = (http.get<B>('http://some.2')); } const [ { data: a }, response ] = [Response<A>, Response<B>?] として Promise.all(requestList) を待機します。 パラダイムジェネリックを定義した後、ジェネリックを使用する方法は 2 つあります。1 つはジェネリック型を渡す方法、もう 1 つは型推論を使用する方法です。 関数 fn<T>(arg: T): T; // ジェネリック関数を定義します。const fn1 = fn<string>('hello'); // 最初の方法は、ジェネリック型文字列を渡します。const fn2 = fn(1); // 2 番目の方法は、パラメータ arg によって渡された型 number から、ジェネリック T の型が number であると推論します。 フラットな配列構造からツリー構造を構築する例: // 変換前のデータ const arr = [ { id: 1、親ID: 0、名前: 'test1'}, { id: 2、親ID: 1、名前: 'test2'}, { id: 3、親 ID: 0、名前: 'test3'} ]; // 変換後 [{ id: 1, parentId: 0, name: 'test1', 子供リスト: [ { id: 2, 親ID: 1, 名前: 'test2', 子供リスト: [] } ] }, { id: 3、親ID: 0、名前: 'test3'、子リスト: [] } ] インターフェースアイテム{ id: 番号; 親ID: 数値; 名前: 文字列; } // 渡されたオプションパラメータからchildrenKeyの型を取得し、それをTreeItemに渡します インターフェースOptions<T extends string> { 子供のキー: T; } type TreeItem<T extends string> = Item & { [T のキー]: TreeItem<T>[] | [] }; 関数 listToTree<T extends string = 'children'>(list: Item[], options: Options<T>): TreeItem<T>[] を宣言します。 listToTree(arr, { childrenKey: 'childrenList' }).forEach(i => i.childrenList) 推測するextends 条件文で推論される型変数を表します。 型 ParamType<T> = T は (param: infer P) => any ? P : T を拡張します。 つまり、T を (param: infer P) => any に割り当てることができる場合、結果は (param: infer P) => any 型のパラメーター P になり、それ以外の場合は T を返します。 インターフェース ユーザー { 名前: 文字列; 年齢: 番号; } 型 Func = (user: User) => void type Param = ParamType<Func>; // Param = User type AA = ParamType<string>; // 文字列 例: // [文字列, 数値] -> 文字列 | 数値 type ElementOf<T> = T は Array<infer E> を拡張します。E : never; タイプTTuple = [文字列、数値]; type ToUnion = ElementOf<TTuple>; // 文字列 | 数値 // T1 | T2 -> T1 & T2 型 UnionToIntersection<U> = (U は any ? (k: U) => void : never) を拡張し ((k: infer I) => void) ? I : never; type Result = UnionToIntersection<T1 | T2>; // T1 & T2 要約するTypescript は型の制限に関して非常に強力です。記事数が限られているため、和集合型、交差型など他の型もあります。読者は自分で情報を確認できます。パラダイムとそのさまざまな組み合わせに初めて触れるときは、慣れていないと感じるかもしれません。その後、ゆっくりとプロジェクトに適用し、バグを最小限に抑えるようにします。 これで、Typescript の実用的なヒントに関するこの記事は終了です。Typescript のより関連性の高い実用的なヒントについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: MySQL の on と where における左結合設定条件の使用法の違いの分析
>>: mysql5.7 の新しい json フィールド タイプの使用例の分析
問題の説明html <iframe id="h5Content" src=...
以前 HTML を解析したことがあるので、今日は Vue ドラッグ アンド ドロップを使用して、Ku...
Linuxインスタンスでシステムディスクを初期化した後、データディスクを再マウントするLinux イ...
1. Windows システムでは、JDK のインストールなど、多くのソフトウェアのインストールで...
序文:ストレージ エンジンはデータベースの中核です。MySQL の場合、ストレージ エンジンはプラグ...
目次序文仮想DOM仮想DOMとは仮想DOMの利点レンダリング関数とは何ですか? jsx Vue3 で...
1. はじめにイメージマップを使用すると、画像の領域をホットスポットとして指定できます。この領域にマ...
IE8 の新機能 Web スライス (Web スライス) Microsoft は 3 月 20 日...
ホストとコンテナ間でファイルを転送するには、コンテナの完全な ID が必要です。取得方法は以下の通り...
1つ: 1.セマンティック タグは単なる HTML であり、CSS にはセマンティクスはありません...
デフォルトでは、Nginx は IP アドレスごとに 1 つの SSL 証明書のみをサポートします。...
【背景】最近勉強中に非常に恥ずかしいことに遭遇しました。MySQL のパスワードを忘れてしまい、My...
まず効果を見てみましょう: マウスを画像の上に移動すると、影の効果とテキスト/アイコンが追加されます...
いくつかの Qt インターフェース プログラムを作成しましたが、Qt 環境がインストールされていない...
目次1. 重複排除前後のデータの比較2. 使い方1. フィルターとマップを使用する2. 削減を使用す...