TypeScript使用Omit移除React组件接口嵌套属性的方法
问题根源
之前的类型写法不生效,核心原因是Omit是面向普通对象类型的工具类型,而LogoBoxTypeBase属于React.FC函数类型。直接对函数类型调用Omit,只会尝试删除函数对象本身挂载的静态属性(比如displayName、defaultProps这类),根本不会修改函数入参(也就是组件Props)的结构,自然没法移除必填的img属性校验。
正确实现方式
不要直接修改组件的函数类型,先提取原始组件的完整Props类型,调整Props结构后再关联到封装的组件上即可,代码如下:
import { LogoBox as LogoBoxBase } from "@lc/ui"; import type { LogoBoxProps as LogoBoxPropsBase } from "@lc/ui"; // 提取原始组件的完整Props类型,移除内部已经写死的必填img属性 // 如果封装时新增了自定义props,也可以在这里通过交叉类型补充 type AppLogoBoxProps = Omit<React.ComponentProps<typeof LogoBoxBase>, 'img'>; // 直接给组件入参标注修改后的Props类型,TS会自动推导组件的正确类型 export const LogoBox = ({ className, children, ...rest }: AppLogoBoxProps) => { return ( <LogoBoxBase // 内置固定的img传值,不需要外部传入 img={<img className="navigation__logo" src="assets/img/logo_small.svg" alt="Logo of the thing" />} className={className} {...rest} > {children && <h1>{children}</h1>} </LogoBoxBase> ); };
补充说明
- 推荐用
React.ComponentProps<typeof 原始组件>提取组件Props类型,比直接引入库导出的Props类型更可靠,能自动包含组件继承的HTML属性、原生事件类型等。 - 如果需要显式声明封装后组件的函数类型,可以用修改后的Props重新构造FC类型:
type AppLogoBoxType = React.FC<AppLogoBoxProps>; export const LogoBox: AppLogoBoxType = ({ /* 入参逻辑不变 */ }) => { /* 渲染逻辑不变 */ } - 封装时记得把接收的
className和剩余props透传给原始组件,避免属性、事件丢失。
内容的提问来源于stack exchange,提问作者Nachtfunke
相关产品推荐
相关产品推荐

