Rumah >hujung hadapan web >tutorial js >Kongsi soalan temuduga TS yang bagus (termasuk 3 tahap) dan lihat tahap mana yang anda boleh jawab!

Kongsi soalan temuduga TS yang bagus (termasuk 3 tahap) dan lihat tahap mana yang anda boleh jawab!

青灯夜游
青灯夜游ke hadapan
2023-01-13 20:05:292771semak imbas

Kongsi soalan temuduga TS yang bagus (termasuk 3 tahap) dan lihat tahap mana yang anda boleh jawab!

Baru-baru ini saya terjumpa soalan temuduga TS yang bagus dan ingin berkongsinya.

Soalan ini mempunyai 3 tahap, mari kita lihat satu persatu.

Keperluan untuk tahap pertama adalah seperti berikut:

Laksanakan fungsi zip untuk menggabungkan elemen dua tatasusunan mengikut tertib, contohnya, input [1,2,3] , [4,5,6], kembali [[1,4], [2,5],[3,6]]

Lapisan ini untuk mengambil daripada dua tatasusunan setiap kali Selepas bergabung elemen, masukkannya ke dalam tatasusunan, dan kemudian teruskan memproses yang seterusnya, dan teruskan proses ini secara rekursif sehingga tatasusunan kosong.

function zip(target, source) {
  if (!target.length || !source.length) return [];

  const [one, ...rest1] = target;
  const [other, ...rest2] = source;

  return [[one, other], ...zip(rest1, rest2)];
}

Hasilnya betul:

Tahap pertama agak mudah, kemudian mari kita lihat keperluan tahap kedua:

Tentukan jenis ts untuk fungsi zip ini (dua cara penulisan)

Terdapat dua bentuk definisi fungsi:

Isytihar fungsi terus melalui fungsi:

function func() {}

dan mengisytiharkan fungsi tanpa nama dan menetapkannya kepada pembolehubah:

const func = () => {}

Jenis parameter dan nilai pulangan adalah kedua-dua tatasusunan, tetapi jenis khusus tidak diketahui, jadi anda boleh menulis tidak diketahui[].

Jadi takrifan kedua-dua jenis fungsi adalah seperti ini:

Ia juga merupakan fungsi pengisytiharan fungsi langsung jenis dan pengisytiharan antara muka Jenis fungsi kemudiannya ditambah kepada jenis pembolehubah kedua-dua cara.

Oleh kerana jenis elemen tertentu tidak diketahui, tidak diketahui digunakan.

Anda boleh bertanya di sini perbezaan antara mana-mana dan tidak diketahui:

Kedua-dua mana-mana dan tidak diketahui boleh menerima apa-apa jenis:

Tetapi mana-mana boleh juga Berikan kepada mana-mana jenis, tetapi tidak diketahui.

Ini hanya digunakan untuk menerima jenis lain, jadi tidak diketahui adalah lebih sesuai dan lebih selamat daripada mana-mana.

Tahap ini juga merupakan sintaks ts yang agak asas, dan tahap ketiga menjadi lebih sukar:

Gunakan pengaturcaraan jenis untuk mencapai petunjuk jenis yang tepat, seperti lulus parameter [1, 2, 3], [4,5,6], maka jenis nilai pulangan harus digesa [[1,4], [2,5],[3,6]]

di sini Jika jenis nilai pulangan diperlukan untuk tepat, kita mesti menjana jenis nilai pulangan secara dinamik berdasarkan jenis parameter.

Itu sahaja:

mengisytiharkan dua jenis parameter Sasaran dan Sumber, dan kekangan tidak diketahui[], iaitu jenis tatasusunan dengan sebarang jenis elemen.

Dua parameter jenis ini ialah jenis dua parameter yang diluluskan.

Nilai pulangan dikira melalui Zip.

Kemudian kita perlu melaksanakan jenis Zip lanjutan:

Parameter jenis yang dihantar ialah dua jenis tatasusunan, dan kita juga perlu mengekstrak setiap elemen daripadanya dan menggabungkannya bersama-sama.

Ekstrak elemen menggunakan padanan corak:

Jadi jenis ini boleh ditakrifkan seperti ini:

type Zip<One extends unknown[], Other extends unknown[]> =
    One extends [infer OneFirst,...infer Rest1]
      ? Other extends [infer OtherFirst, ...infer Rest2]
        ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>]
        : []
      : [];

Ekstrak elemen pertama dari dua tatasusunan masing-masing dan bina tatasusunan baharu. Kemudian lakukan ini secara rekursif untuk tatasusunan yang tinggal sehingga tatasusunan kosong.

Ini mencapai jenis lanjutan yang kita inginkan:

Tetapi jika anda menambahkannya sebagai nilai pulangan kepada fungsi, ralat akan dilaporkan:

Oleh kerana kami tidak tahu apakah parameter apabila kami mengisytiharkan fungsi, kami secara semula jadi tidak boleh mengira nilai Zip7a84628107aa2ed3eaaf3b089e111d01, jadi akan ada jenis yang tidak sepadan di sini:

Apa yang perlu kita lakukan?

boleh diselesaikan dengan lebihan fungsi:

ts menyokong lebihan fungsi, anda boleh menulis definisi jenis bagi pelbagai jenis fungsi dengan nama yang sama, dan akhirnya tulis Implementasi fungsi, supaya apabila fungsi ini digunakan, jenis fungsi akan dipadankan mengikut jenis parameter.

Fungsi yang kami gunakan pengaturcaraan jenis tidak akan melaporkan ralat jika ia ditulis dengan cara ini.

Mari lihat:

Mengapa jenis nilai pulangan salah?

Sebenarnya, jenis fungsi pemadanan adalah betul pada masa ini, tetapi yang disimpulkan bukan jenis literal.

Anda boleh menambah sebagai const pada masa ini.

Tetapi menambah sebagai const akan menyimpulkan baca sahaja [1,2,3]

Jenis ini tidak Ia sepadan , jadi kita perlu menambah baca sahaja:

pada pengisytiharan parameter jenis, tetapi jenis fungsi Zip tidak sepadan lagi.

Adakah kita perlu menambah baca sahaja pada semua tempat di mana jenis ini digunakan?

Tidak, bolehkah kita mengalih keluar pengubahsuaian baca sahaja?

Skrip taip mempunyai jenis lanjutan terbina dalam baca sahaja:

Anda boleh menambah pengubahsuaian baca sahaja pada setiap indeks jenis indeks:

Tetapi tiada jenis lanjutan tanpa pengubahsuaian baca sahaja Kami boleh melaksanakannya sendiri:

Bina jenis indeks baharu menggunakan jenis pemetaan. sintaks Menambah -baca sahaja bermaksud mengalih keluar pengubahsuaian baca sahaja.

Sesetengah pelajar mungkin bertanya, adakah jenis tatasusunan juga jenis indeks?

Ya, jenis indeks ialah jenis yang mengagregatkan berbilang elemen, jadi objek, tatasusunan dan kelas semuanya.

Jadi kita boleh menggunakannya secara semula jadi pada tatasusunan:

(Setepatnya, ia dipanggil tuple. Tuple mempunyai bilangan elemen tetap. Tatasusunan )

Kemudian kita hanya perlu menggunakan Mutable untuk mengalih keluar baca sahaja sebelum memasukkan Zip:

Mari cuba lagi:

Selesai! Sekarang jenis nilai pulangan adalah betul.

Tetapi ada masalah lain Jika literal tidak diteruskan, jenis literal tidak dapat disimpulkan Ini nampaknya salah:

Tetapi. bukankah kita semua mengisytiharkan jenis terlebih muatan?

Jika jenis literal tidak dapat disimpulkan, ia sepatutnya sepadan dengan ini:

Tetapi sebenarnya ia sepadan dengan yang pertama:

Pada masa ini, anda hanya perlu menukar susunan dua jenis fungsi:

Di kali ini, situasi dengan parameter literal masih betul:

Kenapa?

Oleh kerana jenis fungsi terlampau beban dipadankan dari atas ke bawah, selagi satu dipadankan, ia akan digunakan.

Dalam kes nilai bukan literal, jenisnya ialah nombor[], yang boleh sepadan dengan jenis yang tidak diketahui[], supaya jenis fungsi itu berkuat kuasa.

Dalam kes literal, terbitan adalah baca sahaja [1,2,3], dengan baca sahaja supaya ia tidak sepadan dengan tidak diketahui[] dan terus sepadan, cuma Jenis fungsi dengan parameter jenis telah dipadankan.

Dengan cara ini jenis fungsi yang sesuai digunakan dalam kedua-dua kes.

Kod keseluruhan adalah seperti ini:

type Zip<One extends unknown[], Other extends unknown[]> = One extends [
  infer OneFirst,
  ...infer Rest1
]
  ? Other extends [infer OtherFirst, ...infer Rest2]
    ? [[OneFirst, OtherFirst], ...Zip<Rest1, Rest2>]
    : []
  : [];

type Mutable<Obj> = {
  -readonly [Key in keyof Obj]: Obj[Key];
};

function zip(target: unknown[], source: unknown[]): unknown[];

function zip<Target extends readonly unknown[], Source extends readonly unknown[]>(
  target: Target,
  source: Source
): Zip<Mutable<Target>, Mutable<Source>>;

function zip(target: unknown[], source: unknown[]) {
  if (!target.length || !source.length) return [];

  const [one, ...rest1] = target;
  const [other, ...rest2] = source;

  return [[one, other], ...zip(rest1, rest2)];
}

const result = zip([1, 2, 3] as const, [4, 5, 6] as const);

const arr1 = [1, 2, 3];
const arr2 = [4, &#39;5&#39;, 6];

const result2 = zip(arr1, arr2);

ts playground 地址

总结

今天我们做了一道综合的 ts 面试题,一共有三层:

第一层实现 js 的逻辑,用递归或者循环都能实现。

第二层给函数加上类型,用 function 声明类型和 interface 声明函数类型两种方式,参数和返回值都是 unknown[]。

第三层是用类型编程实现精准的类型提示,这一层需要拿到参数的类型,通过提取元素的类型并构造出新的数组类型返回。还要通过函数重载的方式来声明类型,并且要注意重载类型的声明顺序。

as const 能够让字面量推导出字面量类型,但会带有 readonly 修饰,可以自己写映射类型来去掉这个修饰。

其实这也是我们学习 ts 的顺序,我们先要能把 js 逻辑写出来,然后知道怎么给函数、class 等加 ts 类型,之后学习类型编程,知道怎么动态生成类型。

其中类型编程是 ts 最难的部分,也是最强大的部分。攻克了这一层,ts 就可以说学的差不多了。

【相关推荐:javascript学习教程

Atas ialah kandungan terperinci Kongsi soalan temuduga TS yang bagus (termasuk 3 tahap) dan lihat tahap mana yang anda boleh jawab!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam