React useEffect返回值类型不匹配:如何正确进行类型约束?
React useEffect中Socket.io的TypeScript类型错误解决方法
问题
在React的useEffect中遇到TypeScript类型错误,不想通过类型转换或把useEffect返回值设为any这种临时方案解决,需要正确的类型约束处理。
代码示例
import React, { useContext, useEffect, useState } from "react"; import type { Socket } from "socket.io-client"; import io from "socket.io-client"; interface SocketProviderInterface { id: string; children: JSX.Element; } const SocketContext = React.createContext<Socket | null>(null); export const useSocket = () => { return useContext(SocketContext); }; export const SocketProvider = ({ id, children }: SocketProviderInterface) => { const [socket, setSocket] = useState<Socket | null>(null); useEffect(() => { const newSocket = io(`http://localhost:3333`, { query: { id } }); setSocket(newSocket); return () => newSocket.close(); }, [id]); return ( <SocketContext.Provider value={socket}>{children}</SocketContext.Provider> ); };
错误信息
function(): () => Socket<DefaultEventsMap, DefaultEventsMap> 类型“() => () => Socket<DefaultEventsMap, DefaultEventsMap>”的参数不能赋给类型“EffectCallback”的参数。 类型“() => Socket<DefaultEventsMap, DefaultEventsMap>”不能赋给类型“void | Destructor”。 类型“() => Socket<DefaultEventsMap, DefaultEventsMap>”不能赋给类型“Destructor”。 类型“Socket<DefaultEventsMap, DefaultEventsMap>”不能赋给类型“void | { [UNDEFINED_VOID_ONLY]: never; }”。ts(2345)
解决方案
错误根源是newSocket.close()方法会返回Socket实例本身,而useEffect的清理函数(Destructor)要求返回值必须是void或符合特定约束的类型。之前的箭头函数省略大括号,会直接返回close()的结果(即Socket实例),导致类型不匹配。
只需修改清理函数的写法,确保它不返回任何值:
useEffect(() => { const newSocket = io(`http://localhost:3333`, { query: { id } }); setSocket(newSocket); // 改为带大括号的函数,明确不返回值 return () => { newSocket.close(); }; }, [id]);
调整后,清理函数的返回值为void,完全符合TypeScript对EffectCallback的类型要求,无需额外类型转换或any类型。
内容的提问来源于stack exchange,提问作者Blitva
相关产品推荐
相关产品推荐

