使用打字稿自定义延迟加载函数

问题描述 投票:0回答:1

下面是我在 React 和 Typescript 中使用延迟加载时的愿望,但看起来很糟糕 我希望我的代码在使用 typescript 时尽可能准确(目前我正在使用 as ,有些地方没有意义)。请帮助我!!!

import React from "react";

type LazyExportDefault = () => Promise<{ default: React.ComponentType<any> }>;
type ReturnTypeExportLazy = React.LazyExoticComponent<React.ComponentType<any>>;

export function lazyImport<
  T extends React.ComponentType<any>,
  I extends { [K2 in K]: T },
  K extends keyof I
>(factory: () => Promise<I>, name?: K): ReturnTypeExportLazy {
  if (!name) {
    return React.lazy(
      factory as unknown as LazyExportDefault
    ) as ReturnTypeExportLazy;
  }
  return React.lazy(() =>
    factory().then((module) => ({ default: module[name] }))
  );
}
// Usage:
// 1. Exporting declarations: const Home = lazyImport(() => import("./Home"), "Home");
// 2. Default exports: const Home = lazyImport(() => import("./Home"));```


I want my code to be as accurate as possible when using typescript (Currently I'm using as and some places don't make sense). Please help me!!!
reactjs lazy-loading
1个回答
-1
投票

当然,您可以通过创建类型安全函数来提高使用 TypeScript 延迟加载代码的准确性,该函数允许命名导出和默认导出,而无需使用任何类型断言。您可以通过使用 TypeScript 泛型和类型推断来实现这一点。

您可以尝试以下方法:

import React, { ComponentType, LazyExoticComponent } from "react";

type NamedExports<T> = { [key: string]: T };
type LazyExport<T extends ComponentType<any>> = () => Promise<{
  default: T;
}>;

export function lazyImport<T extends ComponentType<any>>(
  factory: LazyExport<T>
): LazyExoticComponent<T>;

export function lazyImport<T extends ComponentType<any>, K extends keyof T>(
  factory: () => Promise<NamedExports<T>>,
  name: K
): LazyExoticComponent<T[K]>;

export function lazyImport(factory: any, name?: any) {
  if (!name) {
    return React.lazy(factory as LazyExport<any>);
  }
  return React.lazy(() =>
    factory().then((module: NamedExports<any>) => ({ default: module[name] }))
  );
}

// Usage:

// For default exports:
const HomeDefault = lazyImport(() => import("./Home"));

// For named exports:
const HomeNamed = lazyImport(() => import("./Home"), "Home");
© www.soinside.com 2019 - 2024. All rights reserved.