typescript bagaimana cara menguji apakah dua generik setara?


Apa yang ingin saya capai adalah sesuatu yang sejalan dengan:

type AType<T, U> = (T is Equal U) ? T : [T, U]

[EDIT] berdasarkan komentar, izinkan saya mengubahnya dengan contoh praktis:
Misalkan T adalah UInt8Array, kesamaan terjadi jika U juga merupakan UInt8Array.
Kesetaraan didefinisikan oleh tipe yang sama.

[EDIT 2] Berdasarkan jawaban @daniel-hilgarth
Ini tidak berfungsi sebagai T extends U dalam penggunaan praktis (lihat di bawah) jika kita mengasumsikan T dan U adalah angka, T akan di-cast ke instance dari angka yang diberikan, sehingga T tidak akan menjadi number tetapi T akan menjadi 2 yang memperluas tipe number. Jadi jika U adalah 3, itu tidak akan memperluas 2

Maaf jika tidak jelas, silakan periksa implementasi di bawah ini

type AType<T, U> = T extends U ? U extends T ? T : [T, U] : [T, U]

const fn = <T extends string | number, U extends string | number>(
  x: T,
  y: U,
): AType<T, U> => {
  throw new Error ('Yet to implement !')
}

const a = fn (2, 2)    // correct number
const b = fn (2, 's')  // correct [number, string]

tetapi

const c = fn (2, 3)    // incorrect [number, number]

Yang saya butuhkan bukan:

  • jika T extends U

Tetapi :

  • jika T extends apa pun U extends

Saya berharap ini menjelaskan pertanyaannya.

Apakah itu bisa dilakukan?

Jawaban #1

Saat ini, untuk tipe kondisional hanya ada satu pertanyaan yang bisa Anda ajukan: extends. Tidak ada equal, tetapi kita bisa menyimulasikannya dengan menggunakan dua pemeriksaan:

type AType<T, U> = T extends U ? U extends T ? T : [T, U] : [T, U]

Pertama, kita memeriksa apakah T memperluas U. Jika ya, kita memeriksa apakah U memperluas T. Kedua kondisi hanya bisa benar secara bersamaan jika T dan U memiliki tipe yang persis sama, jadi kita mengembalikan T.

Ini bekerja dengan benar di Typescript 3.2:

(tautan)

Juga, layak dibaca untuk pemahaman tentang Tipe Kondisional secara umum: https://koerbitz.me/posts/a-look-at-typescripts-conditional-types.html

Artikel terkait