Search code examples
typescriptweb-componentcdnrollupjslit

lit element CDN bundle file: accessing a function contained in the cdn bundle file inside typescript file


I have created a simple lit element bundle file using rollup.config.js. This bundle file is uploaded in Netstorage. This is what my lit element looks like:

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;
  }
}

my rollup.config.json:

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()
  ]
});

I want to access testMethod() inside a typescript file in angular. I have tried accessing the function in an html file and it works like this:


<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()

    }
  });

But I want to be able to call the same thing in a typescript file

I have tried to directly access like this:

in index.html:

and in typescript file, I tried to accessing the testMethod() in the same way.

const el = document.querySelector('my-lit-element');
  const ob = customElements.whenDefined('my-lit-element').then(() => {

    //works
    el.testMethod()

    }
  });

but it does not work, any time I type el.testMethod(), it starts complaining

Property 'testMethod' does not exist on type 'Element'.

Can anyone help me in determining how to call methods inside of cdn js file inside typescript file


Solution

  • It is typescript issue. You can use HTMLElementTagNameMap global interface to provide customElement types.

    Define interface to associate all the web components public methods and properties.

    export interface MyLitComponent extends HTMLElement {
           testMethod():void;
          //Define all the web component properties
    }
    
         
    

    Define HTMLElementTagNameMap inside global interface so that you can use the web component selector in TypeScript as if it were a regular HTML element

    declare global {
              interface HTMLElementTagNameMap {
                'my-lit-element': MyLitComponent;
              }
    }
    

    Now the querySelector return type would be MyLitComponent

    const el = document.querySelector('my-lit-element'); //MyLitComponent
      const ob = customElements.whenDefined('my-lit-element').then(() => {
        el.testMethod()
      }
    });
    

    Example