Rumah >hujung hadapan web >tutorial js >Jenis Bersyarat Rekursif
Anggapkan anda mempunyai gelung untuk dalam dan tiba-tiba menyedari bahawa jenis pembolehubah anda ialah rentetan dan bukan jenis kesatuan literal rentetan. Jadi, anda mendapat ralat buruk ini apabila anda menyusun apl anda dengan tsc, dan yang menjengkelkan IDE kegemaran anda berkemungkinan besar menjerit di bahagian atas serangan mereka:
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)
[!NOTA]
Hanya untuk menunjukkan kepada anda cara ia dilakukan, saya menggunakan os.cpus. Di sana saya cuba mengulangi cpu.times yang merupakan objek. Anda boleh mendapatkan maklumat lanjut di sini.
Jadi inilah kod yang bermasalah:
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! } }
Jadi mari kita masuk ke dalamnya, untuk bahagian pertama kita perlu mencipta jenis utiliti tersuai untuk diri kita sendiri, berikut ialah bagaimana jenis utiliti terakhir kita akan kelihatan seperti:
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;
Jom pecahkan:
[TMasukkan kekunci T]-? ialah "Jenis Dipetakan" yang amat berguna di sini kerana kita tidak tahu nama kunci di dalam objek yang dihantar kepada jenis utiliti ini. Di sini anda menghantar logicalCoreInfo kepadanya atau mana-mana objek lain, kemudian ia melelang melalui kekunci untuk mencipta jenis baharu daripadanya.
Dan -? ada untuk mengalih keluar pilihan supaya kita mempunyai jenis kesatuan literal rentetan bagi semua kunci. Dengan kata lain { keyName?: string } akan dianggap sebagai { keyName: string }.
(TKey memanjangkan K ? kekunci T[TKey] : tidak pernah) semak sama ada kekunci semasa dalam lelaran sepadan dengan kekunci yang diluluskan (K), jika ya ia mengekstrak semua kekunci di dalamnya sebagai jenis kesatuan literal rentetan dan mengembalikannya. Jika tidak, ia tidak mengembalikan apa-apa.
Kemudian jika langkah 3 tiada hasil, ia akan menggunakan jenis utiliti ini secara rekursif pada T[Tkey], dengan cara ini fungsi utiliti kami berfungsi pada objek bersarang juga. Ini biasanya dikenali sebagai "Jenis Bersyarat Rekursif".
Akhir sekali kami meminta ia mengambil gabungan semua jenis yang dijana oleh jenis yang dipetakan. Pendek kata kami sedang meratakan struktur bersarang.
Jadi sekarang masa untuk menggunakannya:
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]; // ...
Atas ialah kandungan terperinci Jenis Bersyarat Rekursif. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!