如何在Angular TypeScript中调用CDN引入的Lit Element组件方法
解决Angular TypeScript调用CDN引入的Lit组件方法报错问题
问题背景
通过Rollup打包Lit Element组件并上传至CDN后,在HTML中直接调用组件方法可正常运行,但在Angular TypeScript文件中调用时,TypeScript提示错误:
Property 'testMethod' does not exist on type 'Element'.
相关代码
Lit Element组件代码
import {customElement} from "lit/decorators.js"; import {LitElement} from "lit"; @customElement('my-lit-element') export class MyLitElement extends LitElement { constructor() { super(); console.log('this is test log'); } /** * invoked when a component is added to the document's DOM */ connectedCallback() { super.connectedCallback(); } testMethod() { console.log('Hi from testMethod()'); } } declare global { interface HTMLElementTagNameMap { 'my-lit-element': MyLitElement; } }
Rollup配置文件rollup.config.js
import merge from 'deepmerge'; import { createSpaConfig } from '@open-wc/building-rollup'; import json from "@rollup/plugin-json" // import copy from 'rollup-plugin-copy' import pkg from './package.json' const baseConfig = createSpaConfig({ developmentMode: process.env.ROLLUP_WATCH === 'true', injectServiceWorker: false }); export default merge(baseConfig, { // any <script type="module"> inside will be bundled by rollup input: './index.html', plugins: [ // ... other rollup plugins json() ] });
HTML中正常运行的调用代码
<script type="module" src="https:path_to_my-lit-element-cdn_bundleFile.js"></script> <my-lit-element></my-lit-element> <script> const el = document.querySelector('my-lit-element'); const ob = customElements.whenDefined('my-lit-element').then(() => { // works el.testMethod() }); </script>
解决方案
方法1:类型断言(快速临时解决)
直接告知TypeScript查询到的元素为目标组件类型,可快速绕过类型检查:
// 在Angular组件的TS文件中,建议在ngAfterViewInit钩子中执行 ngAfterViewInit() { customElements.whenDefined('my-lit-element').then(() => { // 直接断言类型 const el = document.querySelector('my-lit-element') as MyLitElement; el.testMethod(); }); }
若TS未识别MyLitElement,可先临时声明接口过渡:
// 临时声明组件类型接口 declare interface MyLitElement extends HTMLElement { testMethod(): void; } ngAfterViewInit() { customElements.whenDefined('my-lit-element').then(() => { const el = document.querySelector('my-lit-element') as MyLitElement; el.testMethod(); }); }
方法2:引入组件类型定义文件(规范方案)
如果Lit组件打包时输出了.d.ts类型定义文件,将该文件复制到Angular项目的src/types/目录下,然后在tsconfig.json中配置类型路径:
{ "compilerOptions": { "typeRoots": [ "./node_modules/@types", "./src/types" ] } }
配置完成后,Angular的TypeScript会自动识别组件类型,无需额外断言。
方法3:全局扩展类型映射(与Lit组件保持一致)
在Angular项目中新建或修改src/typings.d.ts文件,添加全局类型声明:
declare global { interface HTMLElementTagNameMap { 'my-lit-element': MyLitElement; } interface MyLitElement extends HTMLElement { testMethod(): void; } } export {};
此方式会让document.querySelector('my-lit-element')自动推断为MyLitElement类型,TypeScript不会再抛出错误。
注意事项
- 必须通过
customElements.whenDefined等待组件注册完成后再调用方法,避免DOM元素未初始化导致的报错。 - 在Angular中,建议在
ngAfterViewInit生命周期钩子中执行DOM查询操作,确保视图已渲染完成。
内容的提问来源于stack exchange,提问作者Pragati Prakash
相关产品推荐
相关产品推荐

