使用forwardRef传递ref属性时出现TypeScript类型错误
问题:转发Ref的容器组件类型错误,导致Styled组件无法接收Ref
我在为转发ref的容器组件添加类型时遇到了TypeScript错误,相关代码如下:
Container.tsx
import * as React from "react"; import styled from "styled-components"; const Wrapper = styled.div``; interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> { children: React.ReactNode; } const Container: React.FC<ContainerProps> = React.memo( React.forwardRef((props, ref: React.Ref<HTMLDivElement>) => { return <Wrapper ref={ref} {...props} />; }) ); export default Container;
Typography.tsx
import * as React from "react"; import styled from "styled-components"; import Container from "./Container"; const ContainerStyled = styled(Container)``; interface TypographyProps { children: React.ReactNode; } const Typography: React.FC<TypographyProps> = React.memo(({ children }) => { const handleContainerRef = React.useCallback((ref: HTMLDivElement) => { console.log("ref", ref); }, []); return <ContainerStyled ref={handleContainerRef}>{children}</ContainerStyled>; // ^^^ Property 'ref' does not exist on type }); export default Typography;
错误原因
- 错误的组件类型标注:你把
Container的类型设为React.FC<ContainerProps>,但React.forwardRef返回的是ForwardRefExoticComponent类型,自带ref属性的类型定义。用React.FC覆盖会丢失这部分信息,导致styled后的组件无法识别ref属性。 - 冗余的children定义:
React.HTMLAttributes<HTMLDivElement>已经包含了children属性,ContainerProps里不需要重复声明。
修正方案
修正Container组件的类型
去掉React.FC<ContainerProps>的手动标注,让TypeScript自动推导forwardRef返回的类型,或者显式使用正确的转发ref类型:
import * as React from "react"; import styled from "styled-components"; const Wrapper = styled.div``; // HTMLAttributes已包含children,无需重复定义 interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {} // 推荐:让TypeScript自动推导类型 const Container = React.memo( React.forwardRef<HTMLDivElement, ContainerProps>((props, ref) => { return <Wrapper ref={ref} {...props} />; }) ); // 可选:显式标注类型(效果和自动推导一致) // const Container: React.ForwardRefExoticComponent< // React.PropsWithoutRef<ContainerProps> & React.RefAttributes<HTMLDivElement> // > = React.memo( // React.forwardRef<HTMLDivElement, ContainerProps>((props, ref) => { // return <Wrapper ref={ref} {...props} />; // }) // ); export default Container;
验证效果
修正后,ContainerStyled会正确继承原组件的ref类型,Typography组件中传递ref的代码不再报错,ref能正常传递到内部的div元素。
内容的提问来源于stack exchange,提问作者Mike K
相关产品推荐
相关产品推荐

