typescript - ¿Puedo pasar un tipo genérico como un parámetro de tipo?
Tengo un cliente API que puede ser sincrónico o asincrónico, dependiendo del recuperador. Simplificado drásticamente, es así:
function makeClient<F>({fetcher}: any): any {
return {
query: () => fetcher(`query`) as F<QueryResult>,
toc: () => fetcher(`toc`) as F<TocResult>,
}
}
makeClient<Promise>({fetcher: window.fetch}) // returns promises
makeClient<Identity>({fetcher: fetchSync}) // returns data
Me estoy encontrando con Type 'F' no es genérico. ¿Hay alguna manera de hacer esto?
Aquí está el patio de recreo: https://tsplay.dev/N54OMw
Respuesta #1
Los parámetros de tipo representan tipos compuestos, así que, hasta donde sé, no pueden ser genéricos de la manera que parece que quieres.
Sin embargo, puedes hacer que tu tipo de retorno dependa de un argumento de tipo usando tipos condicionales. Aquí hay una manera muy explícita de hacerlo:
interface QueryResult {}
interface TocResult {}
const fetchSync = () => ({})
// type alias we'll use to signal whether or not to wrap the result in a promise
type PromiseIndicator = 'promise_indicator'
// conditional type that wraps the second argument in a promise if, and only if, the first type argument is set to PromiseIndicator
type ConditionalPromise<T, F> = T extends PromiseIndicator ? Promise<F> : F
// F = string is just a default; it could be anything other than PromiseIndicator
function makeClient<F = string>({fetcher}: any) {
return {
query: () => fetcher(`query`) as ConditionalPromise<F,QueryResult>,
toc: () => fetcher(`toc`) as ConditionalPromise<F,TocResult>,
}
}
makeClient(fetchSync)
makeClient<PromiseIndicator>(fetchSync)
Sospecho que hay una manera más inteligente de hacer esto en tu código real basándote en el tipo real de fetcher, pero para el fragmento que has proporcionado, esto debería funcionar.
Parque infantil
