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

React TypeScript中如何让AppSection接口实现组件props类型安全?

实现类型安全的最终方案

核心思路是通过泛型绑定组件类型与对应props类型,再利用TypeScript的自动类型推断能力避免手动标注泛型的冗余。

推荐实现(无需手动标注类型)

import IntroductionArea from "../components/IntroductionArea";
import type { ComponentType, ComponentProps, LazyExoticComponent } from "react";

// 泛型接口,将component的类型T与props做绑定
interface AppSection<T extends ComponentType<any>> {
  url: string;
  component: T | LazyExoticComponent<T>;
  props?: ComponentProps<T>;
}

// 工具函数,自动推导数组内每个配置项的组件类型,完成自动校验
const defineAppSections = <T extends ComponentType<any>[]>(
  sections: [...{ [K in keyof T]: AppSection<T[K]> }]
) => sections;

// 直接传入配置数组即可,TS会自动校验每个配置项的props是否匹配对应组件
export const appSections = defineAppSections([
  {
    url: "/home",
    component: IntroductionArea,
    props: {
      text: "Hello World",
      name: "Foo Bar"
      // 此处如果属性数量、类型不符合IntroductionArea的props要求,TS会直接报错
    }
  }
  // 后续新增其他组件配置无需额外标注类型,自动完成校验
]);

渲染时的类型安全

遍历渲染时无需额外类型断言,props会自动匹配对应组件类型:

appSections.map(section => {
  const Component = section.component;
  // 类型完全安全,不会出现props不匹配的报错
  return <Component {...(section.props ?? {})} />;
});

轻量实现(无需额外工具函数,TS 4.9+ 支持)

如果不想新增工具函数,可以用satisfies关键字单独为每个配置项做类型校验:

import IntroductionArea from "../components/IntroductionArea";
import type { ComponentType, ComponentProps, LazyExoticComponent } from "react";

interface AppSection<T extends ComponentType<any>> {
  url: string;
  component: T | LazyExoticComponent<T>;
  props?: ComponentProps<T>;
}

export const appSections = [
  {
    url: "/home",
    component: IntroductionArea,
    props: {
      text: "Hello World",
      name: "Foo Bar"
    }
  } satisfies AppSection<typeof IntroductionArea>,
  // 新增配置时单独加satisfies标注即可
];

内容的提问来源于stack exchange,提问作者Stephen Glass

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:30:03