如何修复向styled-components注入类名时的TypeScript类型错误
修复方案
核心思路是通过泛型绑定输入标签与对应原生属性的类型,既解决联合类型的签名兼容问题,又能自动推导返回组件的属性类型,完全移除any断言。
完整修复后代码
import styled, { ThemedStyledFunction, DefaultTheme } from 'styled-components'; import type { JSX } from 'react'; export function elementWithClass<T extends keyof JSX.IntrinsicElements>(e: T, customClassName: string) { // 泛型锁定具体标签类型,直接解决原[2]处的联合类型签名不兼容报错 const se = styled[e] as ThemedStyledFunction<T, DefaultTheme, JSX.IntrinsicElements[T]>; const res = se.attrs((props: JSX.IntrinsicElements[T]) => ({ className: `${customClassName} ${props.className || ""}` }))``; // 直接返回对应标签的原生属性类型,不需要any,解决原[1]处的属性识别问题 return res as React.FC<JSX.IntrinsicElements[T]>; }
关键修改说明
- 给函数增加泛型约束
T extends keyof JSX.IntrinsicElements,TS会根据传入的具体标签名(比如"a"、"div")锁定对应的类型,不会再将所有标签的类型做联合处理,原[2]处的联合类型签名不兼容报错自然消失。 - 给
attrs的入参绑定对应标签的原生属性类型JSX.IntrinsicElements[T],保证className属性读取的类型安全。 - 返回值直接断言为
React.FC<JSX.IntrinsicElements[T]>,自动继承对应标签的所有原生属性,调用时href、id等原生属性都可以被TS正常识别、提示和校验。
调用验证
按原方案调用不会再报href未知的错误,同时会有原生属性的类型提示:
const Link = elementWithClass("a", "rick-roll") // 此处Link自动继承a标签所有原生属性,href可正常使用 const MyElement: React.FC = () => <Link href="http://rick-roll.com">rick</Link>
内容的提问来源于stack exchange,提问作者Antoine Trouve
相关产品推荐
相关产品推荐

