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
相关产品推荐
相关产品推荐

