@kyzinatra

Как задать тип функции принимающей промисы и возвращающей выполненые промисы?

Я хочу написать хук-обертку, которая бы выполняла динамические импорты и передавала бы их в функцию

export function useEffectWithImports<T extends Promise<any>[]>(
  fn: (a: { [P in keyof T]: Awaited<T[P]> }) => any,
  args: any[],
  imports: T
) {
  useEffect(() => {
    Promise.all(imports).then(res => {
      fn(res);
    });
  }, args);
}


Но когда я использую эту функцию, он не видит что я могу взять из res.

useEffectWithImports(
    ([{ onAuthStateChanged }]) => { // Property 'onAuthStateChanged' does not exist on type '{ default: typeof import...
      onAuthStateChanged(auth, user => {});
    },
    [],
    [import("firebase/auth")]
  );


Как можно поправить?

PS
Если вот так записать, то все работает
useEffect(() => {
    const imports = Promise.all([import("firebase/auth"), import("../../../firebase.config")]);
    imports.then(([{ onAuthStateChanged }, { auth }]) => {})
}, [])
  • Вопрос задан
  • 77 просмотров
Решения вопроса 1
daniel_pr
@daniel_pr
Добавьте [].

T extends Promise<any>[] | []

Лучше передавать импорты через callback, чтобы они каждый раз не импортировались. Вот моя версия:

import { DependencyList, useEffect, useRef } from "react";

type Import = Promise<any>;

type AwaitedImports<T extends Import[]> = { [P in keyof T]: Awaited<T[P]> };

type Resolve<T extends Import[]> = (result: AwaitedImports<T>) => void;

function useEffectWithImports<T extends Import[] | []>(
  resolve: Resolve<T>,
  imports: () => T,
  deps?: DependencyList
) {
  const resolveRef = useRef(resolve);
  const importsRef = useRef(imports);
  resolveRef.current = resolve;
  importsRef.current = imports;

  useEffect(() => {
    const promises = importsRef.current();
    Promise.all(promises)
      .then(resolveRef.current as Resolve<T>)
      .catch(console.error);
  }, deps);
}

useEffectWithImports(
  ([fs, path]) => {},
  () => [import("fs"), import("path")],
  []
);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы