typescript - Yerleşik tür koruyucuları kullanarak `unknown`/`object` değerini belirli bir nesne türüne daraltma
İşte saf bir deneme:
const x: unknown = {a: 1};
if (
typeof x === 'object' &&
x !== null &&
'a' in x &&
typeof x.a === 'number' // error: Property 'a' does not exist on type 'object'.
) {
console.log("x's type is a subtype of {a: number}");
}
Burada ayırt etmek için yerleşik tür koruyucularını kullanmanın bir yolu var mı?
Cevap #1
Şu anda k in o gibi in operatörü ile bir nesne türünü daraltmak yalnızca o bir birleşim türü olduğunda çalışıyor ve sonuç olarak birleşim türü, yalnızca bilinen k anahtarına sahip üyelerle daraltılıyor. Bu, microsoft/TypeScript#15256 içinde uygulanmıştır. Ancak sizin durumunuzda, "a" in x kontrolünü yaptığınızda, x’in görünen türü sadece object türüdür, bu bir birleşim değildir ve bilinen bir "a" anahtarına sahip değildir. Bu nedenle, in operatörü kontrolü sizin için herhangi bir yararlı işlem yapmaz.
microsoft/TypeScript#21732 numaralı açık bir özellik talebi var ve in operatörünün, kontrol edilen özelliğin var olduğunu doğrulayarak birleştirilmiş olmayan girdileri de daraltmasını istiyor. Yani "a" in x gibi bir şey, x değerini object türünden {a: unknown} türüne daraltmalıdır. Bu özelliğin TypeScript'te ne zaman veya uygulanıp uygulanmayacağı belli değil. Şimdilik çeşitli geçici çözümler mevcut.
Örneğin, in öğesinin istediğiniz şekilde davranmasını sağlayan kendi kullanıcı tanımlı tür koruma fonksiyonunuzu oluşturabilir ve sonra bunu in yerine çağırabilirsiniz. Bunu yapmanın bir yolu şunlar olabilir:
function inOperator<K extends string, T extends object>(
k: K, o: T
): o is T & Record<K, unknown> {
return k in o;
}
Ve kullanım durumunuzu karşıladığını gözlemleyin:
const x: unknown = { a: 1 };
if (
typeof x === 'object' &&
x !== null &&
inOperator('a', x) &&
typeof x.a === 'number' // okay
) {
x.a.toFixed(); // okay
console.log("x's type is a subtype of {a: number}");
}
x.a.toFixed() çağrıldığında, x.a başarılı bir şekilde number türüne daraltılmıştır.
Koda yönelik oyun alanı bağlantısı
