TypeScript使用rest语法解构PropsWithAs泛型props时无法推断属性问题
问题原因
该问题是TypeScript对未绑定具体值的泛型交叉类型做剩余解构时的推导限制导致的:
你使用的PropsWithAs泛型本质是目标组件原生Props、as属性相关类型、自定义属性三者的交叉类型。当泛型参数T extends ElementType还未传入具体值时:
- 直接访问
props.fallbackText时,TypeScript只需要校验自定义属性是否存在于交叉类型的固定部分,因此可以正常识别。 - 用
...rest做剩余解构时,TypeScript需要从整个动态泛型类型中排除你显式取出的counter属性,但因为T对应的原生Props范围未确定,类型系统无法完成动态的剩余属性推导,就会丢失rest变量中的自定义属性类型信息。
可行解决方法
方法1:显式标注解构后的rest类型
你可以直接强制指定rest的类型,绕过自动推导的限制:type Props<T extends ElementType = "div"> = PropsWithAs<T,{fallbackText: string;counter: number;}>; const Foo = <T extends ElementType>(props: Props<T>): JSX.Element => { const { fallbackText } = props; // 显式指定解构结构,让rest继承除去counter的所有props类型 const { counter, ...rest }: { counter: number; rest: Omit<Props<T>, 'counter'> } = props; return <Bar {...rest} />; };方法2:显式传递自定义属性,避开rest推导
直接把需要传给子组件的自定义属性从props中取出后单独传递,不需要走rest解构:const Foo = <T extends ElementType>(props: Props<T>): JSX.Element => { // 把所有自定义属性和原生属性分开解构 const { fallbackText, counter, ...nativeProps } = props; // 自定义属性单独传,原生属性走rest return <Bar {...nativeProps} fallbackText={fallbackText} />; };方法3:收窄泛型范围
如果你的组件as属性仅支持有限的几个组件类型,可以给泛型添加固定约束或者默认值,让TypeScript可以提前完成类型推导。
内容的提问来源于stack exchange,提问作者Kavian Rabbani
相关产品推荐
相关产品推荐

