ホームページ >ウェブフロントエンド >jsチュートリアル >再帰的な条件付きタイプ
for in ループがあるとします。変数の型が文字列であり、文字列リテラル共用体型ではないことに突然気づきました。そのため、アプリを tsc でコンパイルしているときにこの醜いエラーが発生し、迷惑なことに、お気に入りの IDE が全力で叫び声を上げる可能性が高くなります。
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ user: number; nice: number; sys: number; idle: number; irq: number; }'. No index signature with a parameter of type 'string' was found on type '{ user: number; nice: number; sys: number; idle: number; irq: number; }'.ts(7053)
[!NOTE]
それがどのように行われるかを示すために、私は os.cpus を使用しています。そこで、オブジェクトである cpu.times をループしようとします。詳細については、こちらをご覧ください。
問題のあるコードは次のとおりです。
import { cpus } from 'os'; const logicalCoresInfo = cpus(); for (const logicalCoreInfo of logicalCoresInfo) { let total = 0; for (const type in logicalCoreInfo.times) { total += logicalCoreInfo.times[type]; // Darn it, TS is upset! } }
それでは本題に入りましょう。最初の部分では、独自にカスタム ユーティリティ タイプを作成する必要があります。最終的なユーティリティ タイプは次のようになります。
type NestedKeysOf<T, K extends PropertyKey> = T extends object ? { [TKey in keyof T]-?: | (TKey extends K ? keyof T[TKey] : never) | NestedKeysOf<T[TKey], K>; }[keyof T] : never;
詳しく見てみましょう:
[TKey in keyof T]-?これは、このユーティリティ タイプに渡されるオブジェクト内のキーの名前がわからないため、ここでは特に便利な「マップされたタイプ」です。ここでは、logicalCoreInfo をオブジェクトまたは他のオブジェクトに渡し、キーを反復処理してキーから新しい型を作成します。
そして -?オプション性を削除して、すべてのキーの文字列リテラル共用体型を取得するためにあります。つまり、 { keyName?: string } は { keyName: string } として扱われます。
(TKey extends K ? keyof T[TKey] : Never) 反復内の現在のキーが渡されたキー (K) と一致するかどうかを確認し、一致する場合は、その中のすべてのキーを文字列リテラル共用体型として抽出します。そしてそれを返します。それ以外の場合は何も返しません。
ステップ 3 で結果が得られなかった場合は、このユーティリティ タイプを T[Tkey] に再帰的に適用します。これにより、ユーティリティ関数はネストされたオブジェクトに対しても動作します。これは一般に「再帰的条件型」として知られています。
最後に、マップされた型によって生成されたすべての型の結合を取得するように要求しています。つまり、入れ子構造を平坦化しています。
それでは、今度はそれを使用します:
interface Person { name: string; address: { street: string; city: string; }; } type KeysOfAddress = NestedKeysOf<Person, 'address'>; // "street" | "city" // Or in our original example: type CpuTimesKeys = NestedKeysOf<typeof logicalCoreInfo, 'times'>; // ... total += logicalCoreInfo.times[type as CpuTimesKeys]; // ...
以上が再帰的な条件付きタイプの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。