Skrip ketikan menyimpulkan bahwa bidang tersebut benar (tidak dapat ditentukan), tanpa pelindung tipe yang ditentukan pengguna

type Item = {
    left?: { photoSrc: string };
};

type ItemRequired = {
    left: { photoSrc: string };
};

const item: Item = {} as any;

if (item.left) {
    const itemRequired: ItemRequired = item; // fails. Typescript still says left may be undefined
    // I'd like Typescript to know that field left is truthy
}

Saya tahu tentang pelindung tipe yang ditentukan pengguna. Misalnya.

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

Pertanyaan saya:

  1. Mengapa TypeScript tidak dapat menyimpulkan bahwa left tidak dapat ditentukan?
  2. Apakah itu berarti saya perlu membuat fungsi type guard untuk setiap variasi tipe yang perlu saya periksa? Bukankah ada cara yang lebih sederhana? Misalnya. Saya berharap ketika berada di dalam cakupan pemeriksaan if yang membuktikan bahwa bidang left tidak dapat ditentukan, saya berharap TypeScript mengetahuinya.

Ini sepertinya kasus yang sangat umum, tetapi saya tidak dapat menemukan jawabannya, mohon maaf jika ada.


person ZenVentzi    schedule 31.05.2020    source sumber


Jawaban (2)


Untuk menjawab pertanyaan Anda:

Saya berasumsi karena TypeScript di sini membuat perbandingan antara dua jenis: Item dan ItemRequired, bukan yang Anda inginkan, yaitu { left:{ photoSrc:string } }.

TypeScript sering kali dapat mengetahui bagian mana dari gabungan tipe yang Anda gunakan tanpa pelindung tipe, namun ini belum cukup sempurna. Ini bersifat situasional mengenai mana yang akan dan tidak akan berhasil, ada banyak kemungkinan situasi.

Sering kali orang ingin pergi tanpa pelindung tipe, dan hal ini dapat dimengerti karena sering kali hal ini tampak seperti kode tambahan yang tidak diperlukan. Tapi itu benar-benar dirancang untuk situasi seperti ini:

const itemIsItemRequired = (item: Item): item is ItemRequired =>
  item.left !== undefined;

if (itemIsItemRequired(item)) {
    const itemRequired: ItemRequired = item; // this works
}
person OliverRadini    schedule 31.05.2020

Saat ini, TypeScript tidak menyimpulkan tipe dari aliran pernyataan bersyarat.

const item: Item = {} as any;
if (item.left) {
    const itemRequired: ItemRequired = item; 
}

Akibatnya, blok kode di atas sebenarnya tidak mempersempit jenis item dari Item menjadi ItemRequired. Oleh karena itu, pada kompiler, Anda mencoba menetapkan dua tipe yang tidak kompatibel - satu di mana left adalah wajib dan lainnya adalah opsional.

Alternatifnya, seperti yang Anda sebutkan, Anda dapat menulis type guard atau sederhananya, Anda dapat melakukan hal berikut.

const itemRequired: ItemRequired = item as ItemRequired;

Namun, pelindung tipe tulisan selalu disarankan.

person Nafiz Ahmed    schedule 31.05.2020