使用Styled Components为泛型组件设置样式的TypeScript错误解决问询
解决styled-components中泛型组件嵌套样式的TypeScript错误
我在尝试用styled-components给泛型组件设置嵌套样式时遇到了TypeScript错误,写法如下:
const StyledParentComponent = styled(ParentComponent)` ${GenericComponent} { ... } `;
报错提示JSX无法分配给某个Interpolation类型。以下是可复现该错误的示例代码:
import styled from "styled-components"; const ParentComponent = () => { return ( <ParentComponentContainer> <GenericComponent value={10} /> </ParentComponentContainer> ); }; interface GenericComponentProps<T> { value: T; className?: string; } const GenericComponent = <T,>({ value, className, }: GenericComponentProps<T>) => { console.log(value); return ( <GenericComponentContainer> Logging generic component value </GenericComponentContainer> ); }; const GenericComponentContainer = styled.div``; const RegularComponent = () => { return <RegularContainer></RegularContainer>; }; const RegularContainer = styled.div``; const ParentComponentContainer = styled.div` // 此处会触发错误 ${GenericComponent} { display: flex; } ${RegularContainer} { display: flex; } `;
下面是几种标准解决方案:
直接使用泛型组件的内部Styled容器
这是最简洁合理的方案,因为你本来就是要给泛型组件内部的元素设置样式,直接引用它的容器组件GenericComponentContainer即可:const ParentComponentContainer = styled.div` ${GenericComponentContainer} { display: flex; } ${RegularContainer} { display: flex; } `;完全避开泛型组件的类型冲突,逻辑也更清晰。
给泛型组件添加styled-components类型注解
如果必须直接引用泛型组件写样式,需要手动给组件添加StyledComponent类型,让TypeScript识别它可以作为样式插值:import styled, { StyledComponent } from "styled-components"; // 定义适配泛型组件的Styled类型 type GenericComponentType<T> = StyledComponent< "div", any, GenericComponentProps<T>, never >; // 给泛型组件添加类型断言 const GenericComponent = (<T,>({ value, className, }: GenericComponentProps<T>) => { console.log(value); // 记得把className传递给内部容器 return ( <GenericComponentContainer className={className}> Logging generic component value </GenericComponentContainer> ); }) as unknown as GenericComponentType<any>;这样修改后,父容器里引用
${GenericComponent}就不会报错了,若需要更严格的类型,可以替换any为具体的泛型约束。使用自定义类名替代组件引用
给泛型组件添加自定义类名,在父容器样式中通过类名选择器设置样式:// 泛型组件添加自定义类名 const GenericComponent = <T,>({ value, className, }: GenericComponentProps<T>) => { console.log(value); return ( <GenericComponentContainer className={`${className} generic-component`}> Logging generic component value </GenericComponentContainer> ); }; // 父容器中用类名写样式 const ParentComponentContainer = styled.div` .generic-component { display: flex; } ${RegularContainer} { display: flex; } `;这种方式完全绕开TypeScript的泛型类型检查,兼容性拉满,适合简单场景。
内容的提问来源于stack exchange,提问作者Curious
相关产品推荐
相关产品推荐

