typescript - Bir koleksiyondaki öğelerin türlerini doğrulamanın kısa ve fonksiyonel bir yolu var mı?


Diyelim ki bir sayfadaki tüm onay kutularının isimlerini toplamak istiyoruz.

En saf çözüm olacağı

const names = [...document.querySelectorAll('input[type=checkbox]')]
    .map(el => el.name);

Bu, tip kontrolünden geçmez çünkü document.querySelectorAll, name özelliğine sahip olmayan bir Element koleksiyonu döndürür.

Bunu düzeltmenin bir yolu, document.querySelectorAll<HTMLInputElement> tür parametresini açıkça belirtmek olabilir.

Bu bir derleyiciyi mutlu ederdi, beni değil: şimdi bu kod tür güvenli değil ve çalışma zamanında başarısız olabilir.

Tip güvenli bir çözüm şöyle görünebilir

const names = [...document.querySelectorAll('input')]
    .filter(el => el.matches('[type=checkbox]'))
    .map(el => el.name);

ama bu kodu daha uzun, daha az anlaşılır yapar ve genel olarak bu çözüm ölçeklenmez (burada demek istediğim, bunu genellikle uygulayamazsınız, çünkü her seçici bu kadar kolay bölünemez).

Ve nihayet, hem statik hem de çalışma zamanı kontrollerine sahip olan

const names = [...document.querySelectorAll('input[type=checkbox]')]
    .reduce((acc, el) => el instanceof HTMLInputElement ? [...acc, el] : acc, [] as HTMLInputElement[])
    .map(el => el.name);

O, en güvenli ama en çirkini.

Son olarak, sorum: Bunu en son seçenek kadar güvenli ama biraz daha okunabilir hâle getirmenin bir yolu yok mu?

Cevap #1

filter ile birlikte bir tür koruyucu kullanarak istenmeyen düğümleri filtreleyebilir ve dizinin türünü değiştirebilirsiniz :

const names = [...document.querySelectorAll('input[type=checkbox]')]
    .filter((el): el is HTMLInputElement => el instanceof HTMLInputElement)
    .map(el => el.name);