如何在SolidJS中正确导入Material 3 Web Components并解决TS错误
在SolidJS中正确配置Material 3 Web Components的TypeScript类型
问题背景
已成功导入Material 3 Web Components(如Tabs组件),组件可正常渲染,但存在TypeScript类型错误。当前导入代码:
import '@material/web/button/filled-button.js'; import '@material/web/button/outlined-button.js'; import '@material/web/checkbox/checkbox.js'; import '@material/web/tabs/tabs.js'; import '@material/web/tabs/secondary-tab.js'; import '@material/web/tabs/primary-tab.js';
使用组件时触发类型错误,尝试过用any临时规避,也尝试导入组件类型扩展SolidJS的JSX类型,但md-primary-tab和md-secondary-tab仍报错,错误信息:
Type 'import("c:/Users/USER/dev/sstart/node_modules/solid-js/types/jsx").JSX.Element' is not assignable to type 'Element'. Type 'undefined' is not assignable to type 'Element'.ts(2322) This JSX tag's 'children' prop expects type 'HTMLCollection' which requires multiple children, but only a single child was provided.ts(2745)
正确配置方案
Material Web Components的类型基于原生Custom Elements,需适配SolidJS的JSX类型系统,以下是规范的解决方式:
1. 精确类型声明(推荐)
创建类型声明文件(如src/types/material-web.d.ts),利用SolidJS提供的ElementProps工具类型包装组件类型,同时修正children的类型兼容问题:
import type { ElementProps } from 'solid-js'; import { MdTabs } from '@material/web/tabs/tabs.js'; import { MdPrimaryTab } from '@material/web/tabs/primary-tab.js'; import { MdSecondaryTab } from '@material/web/tabs/secondary-tab.js'; declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'md-tabs': ElementProps<MdTabs>; 'md-primary-tab': ElementProps<MdPrimaryTab> & { children?: string | JSX.Element }; 'md-secondary-tab': ElementProps<MdSecondaryTab> & { children?: string | JSX.Element }; } } }
2. 配置TypeScript识别声明文件
在tsconfig.json中添加声明文件目录到include数组:
{ "include": ["src/**/*", "src/types/**/*.d.ts"] }
方案说明
ElementProps<T>是SolidJS的工具类型,可将原生/自定义元素的属性转换为JSX兼容格式,自动处理事件绑定、属性映射等SolidJS特有逻辑。- 为
md-primary-tab和md-secondary-tab扩展children类型,是因为Material的类型定义错误地将children标记为HTMLCollection,而SolidJS的JSX中children为字符串或单个/多个元素,覆盖后可解决类型冲突。
批量兼容简化方案
若需快速适配大量Material组件,可使用通配符方式扩展类型,无需逐个导入组件类型(会丢失精确类型提示):
import type { ElementProps } from 'solid-js'; declare module 'solid-js' { namespace JSX { interface IntrinsicElements { [key: `md-${string}`]: ElementProps<any> & { children?: string | JSX.Element | JSX.Element[] }; } } }
内容的提问来源于stack exchange,提问作者Alon Amir
相关产品推荐
相关产品推荐

