Tengo varios módulos (o puentes) que siguen el mismo formato que se muestra a continuación:
export interface Bridge { foo: (a: string, b: boolean, c: string) => number; bar: (a: number, b: number, c: string, d: string) => string; x: (a: string) => boolean; y: () => null; }
Como resultado, necesito crear una capa que haga algún procesamiento if-else para importar el módulo respectivo. Sin embargo, las funciones dentro de estos módulos requerirán un mecanismo alternativo que sea genérico.
export type BridgeFunctions = keyof Bridge;
/* Called when a particular bridge throws an error */ export async function fallback(fnName: BridgeFunctions, ...args: any[]): Promise<any> { const fallbackBridge = await import('./fallbackBridge'); const fn = fallbackBridge[fnName]; return fn(...args); }
Sin embargo, VSCode me devuelve este error:
A spread argument must either have a tuple type or be passed to a rest parameter.ts(2556)
Intenté usar llamar y aplicar, lo que condujo a este error en su lugar:
The 'this' context of type ... is not assignable to method's 'this' of type '(this: any[]) => Promise<any>'.
Según tengo entendido, en Javascript vainilla, pasar argumentos directamente a fn debería funcionar. ¿Cómo emulo lo mismo en TypeScript?
EDITAR:
Los módulos Bridge se utilizan de la siguiente manera:
function getBridge(): Bridge { if (inIOS()) { return await import('./ios'); } // ... return await import ('./web'); }
export function foo(a: string, b: boolean, c: string): number { try { const bridge = await getBridge(); return bridge.foo(a, b, c); } catch (error: any) { // ... if (error.bridge.failed) { return await fallback('foo', a, b, c); } } }
El problema aquí es que sus funciones fallbackBridge requieren una cierta cantidad de parámetros, pero les da el tipo "any[]" que podría tener cualquier longitud.
Puede omitir este error con return fn(...(args as Parameters<typeof fn>));
Así es como lo haría.
Básicamente, desea asegurarse de que el usuario pase argumentos válidos a su función. Para hacer esto, configura los argumentos para que sean los parámetros de la función pasada.
export async function fallback<FN extends keyof Bridge>(fnName: FN, args: Parameters<Bridge[FN]>){
Luego, para evitar el error, simplemente escriba fn
en cualquiera:
const fn = fallbackBridge[fnName] as any; return fn(...args);
Usar any
aquí está bien ya que ya sabe que los tipos son compatibles.