React + TypeScript中使用HTML Popover报错的解决方法
修复React+TypeScript中HTML原生Popover的类型错误
问题场景
在React+TypeScript项目中使用HTML原生popover功能时,编写了如下组件:
function AlertWindow() { return ( <> <button popovertarget='my-popover'>Open Popover</button> <div popover id='my-popover'> Greetings, one and all! </div> </> ); }
出现以下类型错误:
Type '{ children: string; popovertarget: string; }' is not assignable to type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'. Property 'popovertarget' does not exist on type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.
Type '{ children: string; popover: true; id: string; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'. Property 'popover' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
项目配置文件如下:
tsconfig.json
{ "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": false, "noFallthroughCasesInSwitch": true }, "include": ["src", "app.ts"], "references": [ { "path": "./tsconfig.node.json" } ] }
package.json
{ "name": "quick-pkt", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite --host", "build": "tsc && vite build", "gp": "tsc && vite build --config vite.config.gp.ts", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview --host", "prettier": "prettier --check .", "prettier-write": "prettier --write ." }, "dependencies": { "@reduxjs/toolkit": "^1.9.5", "emoji-store": "^1.0.5", "framer-motion": "^10.16.4", "lottie-react": "^2.4.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-lazy-with-preload": "^2.2.1", "react-redux": "^8.1.2", "react-router-dom": "^6.15.0", "swiper": "^10.3.0" }, "devDependencies": { "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "@vitejs/plugin-react-swc": "^3.3.2", "autoprefixer": "^10.4.15", "eslint": "^8.45.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "postcss": "^8.4.29", "prettier": "^3.0.3", "prettier-plugin-tailwindcss": "^0.5.4", "sass": "^1.66.1", "tailwindcss": "^3.3.3", "typescript": "^5.0.2", "vite": "^4.4.5" } }
解决方案
方案1:升级依赖包(推荐)
HTML原生popover是较新的API,TypeScript 5.1+以及@types/react 18.2.21+版本才正式支持其类型定义。当前项目使用的TypeScript(5.0.2)和@types/react(18.2.15)版本过低,执行以下命令升级:
# 升级TypeScript到最新版本 npm install typescript@latest --save-dev # 升级@types/react和@types/react-dom到最新版本 npm install @types/react@latest @types/react-dom@latest --save-dev
升级完成后,TypeScript会自动识别popover、popovertarget等属性,错误将消失。
方案2:手动扩展类型定义(不升级依赖时使用)
如果暂时无法升级依赖,可通过扩展React的HTML属性类型来添加popover相关属性:
- 在项目
src目录下创建types/html.d.ts文件(若没有types文件夹则新建),添加以下内容:
import 'react'; declare module 'react' { // 为所有HTML元素添加popover属性支持 interface HTMLAttributes<T> { popover?: 'auto' | 'manual' | boolean; } // 为button元素添加popovertarget相关属性支持 interface ButtonHTMLAttributes<T> { popovertarget?: string; popovertargetaction?: 'hide' | 'show' | 'toggle'; } }
- 确保
tsconfig.json的include字段包含该文件,当前配置的include: ["src", "app.ts"]已覆盖src目录下的所有文件,无需额外修改。
完成后重启TypeScript语言服务,类型错误即可修复。
内容的提问来源于stack exchange,提问作者Abinash Karmakar
相关产品推荐
相关产品推荐

