在我构建了第一个 Web Component 后,想在使用 TypeScript 的 React 项目中使用它。当我在 React 中添加了它后,得到了一个错误:[ts] Property 'wc-menu-button' does not exist on type 'JSX.IntrinsicElements'. [2339]。
导致这个问题的原因是,React 仅知道标准的 HTML 元素,所以当我添加自定义的元素后,React 无法识别它,并向我展示一个错误。
有两种方案解决这个问题。一种在 Web Component 项目中处理,另一种在 React 项目中处理。
方案一:在 Web Component 中定义类型
如果你是 Web Component 的作者,你可以在 JSX 的 IntrinsicElements 中定义你的组件,如下:
在我构建了第一个 Web Component 后,想在使用 TypeScript 的 React 项目中使用它。当我在 React 中添加了它后,得到了一个错误:
[ts] Property 'wc-menu-button' does not exist on type 'JSX.IntrinsicElements'. [2339]
。导致这个问题的原因是,React 仅知道标准的 HTML 元素,所以当我添加自定义的元素后,React 无法识别它,并向我展示一个错误。
有两种方案解决这个问题。一种在 Web Component 项目中处理,另一种在 React 项目中处理。
方案一:在 Web Component 中定义类型
如果你是 Web Component 的作者,你可以在 JSX 的 IntrinsicElements 中定义你的组件,如下:
你可能会觉的将
my-element
的类型设为 any 并不理想,你是对的。是不是将组件的属性定义为一个接口,让后将组件设置为该类型会更好?像下面这样:这看起来很好。但当你向这个自定义组件设置
key
和ref
属性时,将看到这样的错误[ts] Property 'ref' does not exist on type 'MyElementAttributes'. [2339]
。MyElementAttributes
需要继承 React 的HTMLAttributes
类,如下:现在当你尝试使用 tsc(TypeScript 编译器)编译你的 Web Component 时将报错,因为编译器无法获取
HTMLAttributes
类型。你需要安装@types/react
作为开发时的依赖。但是现在你的 Web Component 项目依赖于 React 类型,这是一种倒退,你基于标准自定义的组件不应该依赖于某个前端框架。你可以依赖 React,也可以将你的组件声明为any
类型,然后编写完备的文档去描述所有属性。或使用一些工具来帮忙
如果你不想自己处理生成
IntrinsicElement
类型的问题,你可以使用 StencilJS 类似的工具来构建你的 Web Component。它将为你处理类型,生成一个全局声明将你的 Web Component 定义在IntrinsicElements
接口中。方案二:在 React 项目中定义类型
与方案一类似。该方案将类型定义在 React 项目中,而不是 Web Component 项目中。我习惯创建一个
declarations.d.ts
文件,然后将类型定义在这里:现在你可以在 React 项目中使用你的 Web Component 了。