You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:15:12