typescript - Kako dobiti tip povratne vrijednosti za određene parametre generičke funkcije?
Želio bih stvoriti tip uslužnog programa koji uzima potpis generičke funkcije i njezine argumente. Trebao bi rezultirati tipom povratne vrijednosti potpisane funkcije kao da je izvršena s danim argumentima.
Pokušao sam ovo:
type GetReturnType<T extends (...args: any) => any, B> = T extends (...args: any) => infer R ? R : never;
Ali svi generici završavaju kao unknown ili never.
Neke primjer funkcija koje bih možda želio proslijediti:
function myFn1<T>(x: T) {
return {
a: x,
}
}
function myFn2<T>(x: T) {
return [x];
}
function myFn3<T>(x: T) {
if (typeof x == "string") {
return "yes" as (T extends string ? "yes" : "no");
} else {
return "no" as (T extends string ? "yes" : "no");
}
}
I kako bih želio da se GetReturnType koristi:
type Return1 = GetReturnType<typeof myFn1, [x: number]>; // expected {a: number}
type Return2 = GetReturnType<typeof myFn2, [x: number]>; // expected number[]
type Return3A = GetReturnType<typeof myFn3, [x: number]>; // expected "no"
type Return3B = GetReturnType<typeof myFn3, [x: string]>; // expected "yes"
Veza za igralište
TypeScript već ima sustav za izvođenje generičkih tipova funkcija. Na primjer, myFn3("some string") će izvesti prvi generički argument kao string, a rezultat koji se vraća će biti "yes". Želio bih iskoristiti ovaj sustav kada pokušavam dobiti tip povratne vrijednosti. Ostala pitanja na SO pitaju kako to učiniti kada su generici poznati, ali ja bih želio znati kako to učiniti kada se generici izvedu.
Odgovor #1
const to = <A>(value: A) => ({ value } as const);
type ApplyTo<A> = ReturnType<typeof to<A>>;
const map = <A extends unknown[]>(value: readonly [...A]) => value.map(to) as {
[K in keyof A]: ApplyTo<A[K]>;
};
type t2 = ReturnType<typeof map<["a", "b", "c"]>>;
// type t2 = [{
// readonly value: "a";
// }, {
// readonly value: "b";
// }, {
// readonly value: "c";
// }]
Mislim da je ovo što bliže može biti. Bilo bi bolje kada bismo mogli proslijediti to kao parametar, ali koliko ja znam, to nije moguće.
Odgovor #2
Isto pitanje, zašto mogu vratiti dodatnu vrijednost
type RX = { id: number; name: string };
type GetProduct = (name: string) => RX;
const getProduct: GetProduct = (name) => ({ id: 123, name, city: "" });
poput Grada ovdje
