Rumah >hujung hadapan web >tutorial js >Jenis Bersyarat Rekursif

Jenis Bersyarat Rekursif

Barbara Streisand
Barbara Streisandasal
2024-12-01 03:00:13459semak imbas

Recursive Conditional Types

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!
  }
}

Betulkan

  1. Kita perlu mengekstrak kunci di dalam logicalCoreInfo.times dan mencipta jenis baharu daripadanya.
  2. Kemudian kita boleh menggunakan penegasan jenis untuk meyakinkan TS bahawa segala-galanya bagus dan kita tahu apa yang berlaku di sini.

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:

  1. T memanjangkan objek ? ... : tidak pernah memberitahu TS untuk melintasi objek bersarang jenis T secara rekursif dan mengekstrak kekunci kunci tertentu di dalam T jika T ialah objek.
  2. [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 }.

  3. (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.

  4. 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".

  5. 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];
// ...

Ruj

  • Kekunci TypeScript daripada jenis objek bersarang.

Atas ialah kandungan terperinci Jenis Bersyarat Rekursif. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn