Typescript: Tipe 'string | undefined' tidak dapat ditetapkan ke tipe 'string'
Ketika saya membuat properti dari sebuah antarmuka menjadi opsional, dan saat menetapkan anggotanya ke variabel lain seperti ini:
interface Person {
name?: string,
age?: string,
gender?: string,
occupation?: string,
}
function getPerson() {
let person = <Person>{name:"John"};
return person;
}
let person: Person = getPerson();
let name1: string = person.name; // <<< Error here
Saya mendapatkan kesalahan seperti berikut:
TS2322: Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
Bagaimana saya bisa mengatasi kesalahan ini?
Jawaban #1
Anda sekarang dapat menggunakan operator pengecekan non-null yang ada di sini tepat untuk kasus penggunaan Anda.
Ini memberi tahu TypeScript bahwa meskipun sesuatu terlihat seperti bisa bernilai null, ia bisa mempercayai Anda bahwa itu tidak:
let name1:string = person.name!;
// ^ note the exclamation mark here
Jawaban #2
Saya tahu ini agak terlambat, tetapi cara lain selain jawaban Yannick untuk menggunakan ! adalah dengan mengubahnya menjadi string sehingga memberi tahu TypeScript: Saya yakin ini adalah string, sehingga mengubahnya.
let name1:string = person.name; // Error here compile time
ke
let name1 = person.name as string; // No error here compile time, runtime though
Ini akan membuat kesalahan hilang, tetapi jika kebetulan ini bukan string, Anda akan mendapatkan kesalahan saat menjalankan program... yang merupakan salah satu alasan kami menggunakan TypeScript untuk memastikan tipe cocok dan menghindari kesalahan seperti itu saat waktu kompilasi.
Jawaban #3
Untuk menghindari kesalahan kompilasi saya menggunakan
let name1:string = person.name || '';
Dan kemudian validasi string kosong.
Jawaban #4
Sejak TypeScript 3.7 Anda dapat menggunakan operator penggabungan null ??. Anda dapat menganggap fitur ini sebagai cara untuk "kembali" ke nilai default saat menangani null atau undefined
let name1:string = person.name ?? '';
Operator ?? dapat menggantikan penggunaan || saat mencoba menggunakan nilai default dan dapat digunakan ketika menangani boolean, angka, dll. di mana || tidak dapat digunakan.
Mulai TypeScript 4, Anda bisa menggunakan operator penugasan ??= seperti a ??= b yang merupakan alternatif dari a=a ?? b;
Jawaban #5
Menurut definisi Anda Person.name bisa null tetapi name1 tidak bisa. Ada dua skenario:
Person.name tidak pernah null
beri tahu kompiler bahwa Anda yakin nama itu tidak null dengan menggunakan !
let name1: string = person.name!;
Person.name bisa bernilai null
tentukan nilai default jika nama bernilai null
let name1: string = person.name ?? "default name";
Jawaban #6
Cara yang lebih siap untuk produksi dalam menangani ini adalah dengan benar-benar memastikan bahwa name ada. Dengan asumsi ini adalah contoh minimal dari proyek yang lebih besar di mana sekelompok orang terlibat, Anda tidak tahu bagaimana getPerson akan berubah di masa depan.
if (!person.name) {
throw new Error("Unexpected error: Missing name");
}
let name1: string = person.name;
Sebagai alternatif, Anda dapat mengetik name1 sebagai string | undefined, dan menangani kasus undefined lebih jauh. Namun, biasanya lebih baik menangani kesalahan tak terduga lebih awal.
Anda juga dapat membiarkan TypeScript menyimpulkan tipe dengan menghilangkan tipe yang eksplisit: let name1=person.name Ini tetap akan mencegah name1 diubah menjadi angka, misalnya.
Jawaban #7
Berikut cara cepat untuk mengetahui apa yang sedang terjadi:
Ketika kamu melakukan hal berikut:
nama? : string
Anda mengatakan kepada TypeScript bahwa itu opsional. Namun, ketika Anda melakukannya:
let name1 : string = person.name; //<<<Error here
Anda tidak memberinya pilihan. Anda perlu memiliki Union pada itu yang mencerminkan tipe yang tidak terdefinisi:
let name1 : string | undefined = person.name; //<<<No error here
Dengan menggunakan jawaban Anda, saya dapat membuat sketsa berikut yang pada dasarnya adalah sebuah Interface, sebuah Kelas, dan sebuah Objek. Saya menemukan pendekatan ini lebih sederhana, tidak masalah jika Anda tidak.
// Interface
interface iPerson {
fname? : string,
age? : number,
gender? : string,
occupation? : string,
get_person?: any
}
// Class Object
class Person implements iPerson {
fname? : string;
age? : number;
gender? : string;
occupation? : string;
get_person?: any = function () {
return this.fname;
}
}
// Object literal
const person1 : Person = {
fname : 'Steve',
age : 8,
gender : 'Male',
occupation : 'IT'
}
const p_name: string | undefined = person1.fname;
// Object instance
const person2: Person = new Person();
person2.fname = 'Steve';
person2.age = 8;
person2.gender = 'Male';
person2.occupation = 'IT';
// Accessing the object literal (person1) and instance (person2)
console.log('person1 : ', p_name);
console.log('person2 : ', person2.get_person());
Jawaban #8
cobalah untuk mengetahui nilai sebenarnya sebelumnya. Jika person memiliki name yang valid, tetapkan ke name1, jika tidak tetapkan undefined.
let name1: string = (person.name) ? person.name : undefined;
