如何将Stencil的IntrinsicElements添加到React的IntrinsicElements中?
嘿,我完全懂你的感受——刚接触TypeScript,想把Stencil组件的类型正确集成到React项目里,虽然当前写法能跑起来,但总觉得是不是有更规范的方式对吧?
首先得告诉你:你现在的思路其实是正确的,只是可以做一些优化让它更符合TypeScript的最佳实践。咱们一步步来理清楚:
先肯定你的现有写法
你通过导入Stencil生成的JSX类型空间,然后全局扩展React的JSX.IntrinsicElements,这个核心逻辑是没问题的——TypeScript就是通过这种方式识别自定义HTML元素类型的,所以你的<my-component>能获得类型提示且不报错,完全是因为这个扩展起了作用。
优化方向:集中管理类型声明
你现在把类型扩展写在组件文件里,虽然能用,但如果项目里有多个组件要用到Stencil元素,就会重复代码。更规范的做法是创建一个全局类型声明文件,比如在React项目的src目录下新建stencil-components.d.ts,把类型扩展的代码放在这里:
// src/stencil-components.d.ts import { JSX as StencilJSX } from 'stencil-project/dist/types/components'; declare global { namespace JSX { // 扩展React的IntrinsicElements,合并Stencil组件的类型 interface IntrinsicElements extends StencilJSX.IntrinsicElements {} } }
这样一来,整个React项目里的所有组件都能自动识别Stencil的自定义元素类型,不用每个组件都重复写declare global的代码。
关于官方文档的补充
你提到的Stencil官方文档里的「Typed Components」部分,其实就是指这种类型集成方式,只是文档没把细节写得太细。另外,如果你不想用kebab-case的原生自定义元素,还可以试试Stencil的@stencil/react-output-target工具——它能自动把Stencil组件包装成React组件(支持驼峰式命名,比如<MyComponent />),同时自动处理类型集成,省去手动扩展IntrinsicElements的步骤。但如果你坚持要用原生的kebab-case元素,那手动扩展类型的方式就是最直接的选择。
最后再确认几个关键点
- 确保你的Stencil项目执行
build后,已经生成了dist/types/components下的类型文件(Stencil默认会自动生成,只要配置没问题) - 检查React项目的
tsconfig.json,确保它能识别到你新建的.d.ts文件(一般只要文件在src目录下,或者在include数组里包含了相关路径就没问题)
备注:内容来源于stack exchange,提问作者Basti

