yazma - Parametreye bağlı olarak Typescript dönüş tipi
Bir parametre olarak boolean türünde bir değer alan ve giriş değerine bağlı olarak iki türden birini döndüren bir fonksiyon yazmaya çalışıyorum. İki yaklaşım buldum:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
if (x) {
return 3;
} else {
return "string";
}
}
Burada, TypeScript Type '3'/'"string"' türü 'B extends true ? number : string' türüne atanamaz. diyor.
Benim diğer yaklaşımım şöyle görünüyor:
function dependsOnParameter(x: true): number;
function dependsOnParameter(x: false): string;
function dependsOnParameter(x: boolean): number | string {
if (x) {
return 3;
} else {
return "string";
}
}
Bu derleniyor; ancak, eğer kendi fonksiyonumu kullanmayı denersem:
function calling(x: boolean) {
dependsOnParameter(x);
}
Ben boolean türündeki argüman, false türündeki parametreye atanamaz hatasını alıyorum.
any kullanmadan istediğimi başarmanın bir yolu var mı?
Cevap #1
Her iki yaklaşım da geçerlidir. Fonksiyonunuz dönüşte koşullu tipler kullanıyorsa, tür onayları kullanması gerekecektir, çünkü TypeScript, serbest bir tür parametresi içerdiğinden dolayı koşullu tipi anlamaya çalışmayacaktır:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
if (x) {
return 3 as any;
} else {
return "string"as any;
}
}
Bu yaklaşım, kaçınmak istediğiniz any öğesini kullanır.
Son imzayı sadece kopyalayarak, tür atamalarına başvurmadan çalıştırabileceğimiz ikinci yaklaşım:
function dependsOnParameter(x: true): number;
function dependsOnParameter(x: false): string;
function dependsOnParameter(x: boolean): number | string
function dependsOnParameter(x: boolean): number | string {
if (x) {
return 3;
} else {
return "string";
}
}
function calling(x: boolean) {
dependsOnParameter(x); // returns number| string
dependsOnParameter(true); // returns number
dependsOnParameter(false); // returns string
}
Son imza uygulama imzasıdır ve halka açık değildir. Onu çoğaltarak erişilebilir hale getirebilirsiniz. Derleyici, iki aşırı yükleme ile true/false’yi birleştirip dönüş tipinin string|number olduğunu belirleyecek kadar akıllı değildir.
Düzenle
Daha az imza için iki yaklaşımı da birleştirebiliriz:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string
function dependsOnParameter(x: boolean): number | string{
if (x) {
return 3;
} else {
return "string";
}
}
Cevap #2
Bu bir yol:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
return (x === true ? 3 : "string") as B extends true ? number : string;
}
Burada, koşulun kendisi (B extends true ? number : string) bir tür olarak kabul edilir. Bu türe Koşullu Tür denir.
