JS项目迁移至TS时使用useRef修改样式出现Typescript错误如何修复?
错误原因
HTMLDivElement.children 返回的是 HTMLCollection 类型,其成员默认类型为通用 Element 类型,该类型没有定义 style 属性,只有 HTMLElement 及其子类才具备 style 属性,因此TS会抛出属性不存在的类型错误。
另外你提供的原代码还存在两个可优化问题:
- JSX结构中
<div className="header--home">没有写闭合标签 - scroll事件直接在组件顶层绑定,会导致每次组件渲染都重复绑定监听器,组件卸载后也不会自动清理,存在内存泄漏风险
修复方案
你可以选择以下任意一种方案解决类型报错:
方案1:使用类型断言(简便写法)
直接将目标元素断言为 HTMLElement 即可绕过类型校验:
import React, { useRef, useEffect } from "react"; const HomeHeader = (): JSX.Element => { const headerRef = useRef<HTMLDivElement>(null); const handleScroll = () => { if (headerRef.current) { try { const offset = window.pageYOffset; const base = headerRef.current.children; // 添加类型断言 (base[0] as HTMLElement).style.backgroundPositionY = offset * 0.2 + "px"; } catch (e) { console.warn("Error"); } } }; // 事件绑定移到useEffect中,统一处理绑定和清理 useEffect(() => { window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); return ( <header> <div className="header--home" ref={headerRef}> <div className="header--home-overlay" /> </div> </header> ); }; export default HomeHeader;
方案2:使用类型守卫(更安全)
先通过 instanceof 判断元素类型再操作,避免类型断言可能带来的类型安全风险,仅需修改handleScroll逻辑即可:
const handleScroll = () => { if (headerRef.current) { try { const offset = window.pageYOffset; const base = headerRef.current.children; const target = base[0]; // 类型守卫判断元素类型 if (target instanceof HTMLElement) { target.style.backgroundPositionY = offset * 0.2 + "px"; } } catch (e) { console.warn("Error"); } } };
内容的提问来源于stack exchange,提问作者Alan Dsilva
相关产品推荐
相关产品推荐

