[React Typescript] Strongly Typing Lazy Loaded Components with Generics

发布时间 2023-08-28 17:56:45作者: Zhentiw

Navigating to the type definition for lazy by CMD + click in local VS Code, or in the DefinitelyTyped repo.

We can see the following definition:

function lazy<T extends ComponentType<any>>(
	factory: () => Promise<{ default: T }>
): LazyExoticComponent<T>;

 

ComponentType<Any>, is helper type to restrict the component must has the prop we passed in.

import { ComponentProps, ComponentType, lazy, Suspense, useMemo } from "react";

type Props<T extends ComponentType<any>> = {
  loader: () => Promise<{ default: T }>;
} & ComponentProps<T>;

function LazyLoad<T extends ComponentType<any>>({
  loader,
  ...props
}: Props<T>) {
  const LazyComponent = useMemo(() => lazy(loader), [loader]);

  return (
    <Suspense fallback={"Loading..."}>
      <LazyComponent {...props} />
    </Suspense>
  );
}

<>
  <LazyLoad loader={() => import("fake-external-component")} id="123" />

  <LazyLoad
    loader={() => import("fake-external-component")}
    // @ts-expect-error number is not assignable to string
    id={123}
  />

  {/* @ts-expect-error id is missing! */}
  <LazyLoad loader={() => import("fake-external-component")} />
</>;