You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React动态导入组件时访问嵌套Loading组件的类型错误问题

解决动态导入React组件时无法访问嵌套Loading组件的TypeScript报错问题

问题场景

给函数组件PersonalDetailsForm添加了嵌套的Loading组件属性,常规导入时能正常访问,但使用dynamic动态导入时,TypeScript报错:

Property 'Loading' does not exist on type 'ComponentType<{}>'.
Property 'Loading' does not exist on type 'ComponentClass<{}, any>'. 

相关代码:
组件文件(personal-details-form.tsx)

const PersonalDetailsForm = () => <h1>Test</h1>
const PersonalDetailsFormLoader = () => {
  return <>loading...</>;
};

PersonalDetailsForm.Loading = PersonalDetailsFormLoader;
export default PersonalDetailsForm

动态导入代码

const PersonalDetailsForm = dynamic(() => import("./personal-details-form"), {
  ssr: false,
  loading: () => <PersonalDetailsForm.Loading />,
});

const loaders = [<TypeSelectionForm.Loading />, <PersonalDetailsForm.Loading />];

问题原因

TypeScript默认将动态导入的组件推断为ComponentType类型,这个类型并不包含我们自定义的Loading属性。而常规导入时,TypeScript能直接识别到组件上扩展的属性,所以不会报错。

解决方案

通过自定义类型扩展组件类型,明确声明组件包含Loading属性,让TypeScript正确识别。

方案1:在组件文件中定义自定义类型

修改personal-details-form.tsx,添加类型定义并断言组件类型:

import type { FC } from 'react';

// 定义包含Loading属性的组件类型
type PersonalDetailsFormType = FC & {
  Loading: FC;
};

const PersonalDetailsForm = () => <h1>Test</h1> as PersonalDetailsFormType;

const PersonalDetailsFormLoader = () => {
  return <>loading...</>;
};

// 此时TypeScript能识别Loading属性
PersonalDetailsForm.Loading = PersonalDetailsFormLoader;

export default PersonalDetailsForm;

在导入文件中指定动态导入的组件类型:

import dynamic from 'next/dynamic';
import type { PersonalDetailsFormType } from './personal-details-form';

const PersonalDetailsForm = dynamic(
  () => import("./personal-details-form").then((mod) => mod.default),
  {
    ssr: false,
    loading: () => <PersonalDetailsFormType.Loading />,
  }
) as unknown as PersonalDetailsFormType;

// 现在可以正常访问Loading组件
const loaders = [<TypeSelectionForm.Loading />, <PersonalDetailsForm.Loading />];

方案2:单独导出Loading组件(更简单)

把Loading组件单独导出,避免在组件未加载时访问其嵌套属性:

// personal-details-form.tsx
export const PersonalDetailsFormLoader = () => {
  return <>loading...</>;
};

const PersonalDetailsForm = () => <h1>Test</h1>;
PersonalDetailsForm.Loading = PersonalDetailsFormLoader;
export default PersonalDetailsForm;

在导入文件中直接使用单独导出的Loading组件:

import dynamic from 'next/dynamic';
import { PersonalDetailsFormLoader } from './personal-details-form';

const PersonalDetailsForm = dynamic(() => import("./personal-details-form"), {
  ssr: false,
  loading: () => <PersonalDetailsFormLoader />,
});

// 组件加载完成后也能正常访问嵌套的Loading属性
const loaders = [<TypeSelectionForm.Loading />, <PersonalDetailsForm.Loading />];

内容的提问来源于stack exchange,提问作者Netlemon Opp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:31:01