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

如何在TypeScript中扩展HTMLElement自定义属性并构建跨框架WebComponent类型包

框架无关WebComponent类型定义npm包解决方案

核心思路

要实现框架无关的WebComponent类型支持,只需通过全局类型扩展实现HTMLElement的自定义属性/标签映射,无需引入React、Vue等框架类型,保证包的通用性。关键是在TypeScript全局命名空间中声明自定义元素的接口、标签映射,同时兼容JSX属性识别(适配React等使用JSX的框架)。

修正index.d.ts类型定义

以下是可正常工作的类型声明文件,需确保文件作为模块导出(避免全局污染且被TypeScript正确识别):

declare global {
  // 映射自定义标签到对应元素类型
  interface HTMLElementTagNameMap {
    'super-awesome': SuperAwesomeElement;
  }

  // 定义自定义元素的实例属性与类型
  interface SuperAwesomeElement extends HTMLElement {
    sourceId: string;
    position: 'left' | 'right' | 'top' | 'bottom';
  }

  // 适配JSX框架(如React)的属性识别
  namespace JSX {
    interface IntrinsicElements {
      'super-awesome': React.DetailedHTMLProps<React.HTMLAttributes<SuperAwesomeElement>, SuperAwesomeElement> & {
        'source-id'?: string;
        position?: 'left' | 'right' | 'top' | 'bottom';
      };
    }
  }
}

// 必须导出空对象,标记文件为模块
export {};

配置文件调整

tsconfig.json

确保编译配置正确生成类型声明,示例配置:

{
  "compilerOptions": {
    "target": "ES2017",
    "module": "ESNext",
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "moduleResolution": "node"
  },
  "include": ["index.d.ts"],
  "exclude": ["node_modules"]
}

package.json

配置包的类型入口、发布文件,确保类型被正确识别:

{
  "name": "super-awesome-webcomponent-types",
  "version": "1.0.0",
  "type": "module",
  "types": "./index.d.ts",
  "files": ["index.d.ts"],
  "scripts": {
    "build": "tsc"
  }
}

WebComponent实现文件(index.js)

无需打包,直接通过script标签引入即可,示例实现:

class SuperAwesomeElement extends HTMLElement {
  static get observedAttributes() {
    return ['source-id', 'position'];
  }

  constructor() {
    super();
    // 可添加shadow DOM等初始化逻辑
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'source-id') {
      this.sourceId = newValue;
    } else if (name === 'position') {
      this.position = newValue;
    }
  }

  get sourceId() {
    return this.getAttribute('source-id');
  }

  set sourceId(value) {
    this.setAttribute('source-id', value);
  }

  get position() {
    return this.getAttribute('position') || 'right';
  }

  set position(value) {
    if (['left', 'right', 'top', 'bottom'].includes(value)) {
      this.setAttribute('position', value);
    }
  }
}

customElements.define('super-awesome', SuperAwesomeElement);

使用说明

  1. 发布该npm包后,在任意框架项目中安装:npm install super-awesome-webcomponent-types
  2. 在项目中引入WebComponent的编译后JS文件(可通过CDN或本地引入)
  3. 直接使用标签:<super-awesome source-id="foo" position="right" />,TypeScript会自动识别属性类型与标签合法性

内容的提问来源于stack exchange,提问作者goellner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:05:21