question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New typings broke custom elements for me

See original GitHub issue

The new typings introduced in #1116 broke custom elements for me. Is there a workaround, am I using JSX.IntrinsicElements wrong or do we need a fix for preact’s typings?

Test case (attach this to test/ts/VNode-test.s):

class TestCE extends HTMLElement {}

declare global {
  namespace JSX {
    interface IntrinsicElements {
      ["test-ce"]: Partial<TestCE>;
    }
  }
}

const MyTestCustomElement = <test-ce><div>hai</div></test-ce>;

Error:

test/ts/VNode-test.tsx:78:30 - error TS2322: Type '{ children: Element; }' is not assignable to type 'Partial<TestCE>'.
  Types of property 'children' are incompatible.
    Type 'Element' is not assignable to type 'HTMLCollection | undefined'.
      Type 'Element' is not assignable to type 'HTMLCollection'.
        Property 'namedItem' is missing in type 'Element'.

const MyTestCustomElement = <test-ce><div>hai</div></test-ce>;

cc @marvinhagemeister

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:49 (33 by maintainers)

github_iconTop GitHub Comments

5reactions
marvinhagemeistercommented, Jul 19, 2019

Thanks for pinging me. I’ll reopen this ticket and mark it as something for the docs. I’m working on the new ones for X and we should write a section about this in the next weeks.

3reactions
andrewigginscommented, Jun 13, 2020

Hmm seems there was a recent fix in TypeScript that may have resolved some of the issues we were seeing that required JSXInternal work arounds. The following fails in 3.9.0-beta but works in 3.9.1-rc

Repo: https://github.com/andrewiggins/cannot-extend-instrinsic-elements-demo/tree/explorations

// module.tsx
export interface ModuleCE {
  instanceProp: string;
}

export interface ModuleCEEvent {
  eventProp: string;
}

export interface ModuleCEAttributes extends preact.JSX.HTMLAttributes {
  ceProp?: string;
  onsomeevent?: (this: ModuleCE, ev: ModuleCEEvent) => void;
}

declare module "preact" {
  namespace JSX {
    interface IntrinsicElements {
      "module-custom-element": ModuleCEAttributes;
    }
  }
}
// app.tsx
import { createElement } from "preact";

export function App() {
  return (
    <div>
      <module-custom-element
        ceProp="ceProp"
        dir="auto" // Inherited prop from HTMLAttributes
        onsomeevent={function (e) {
          console.log(e.eventProp, this.instanceProp);
        }}
      />
    </div>
  );
}

There are over 100 fixed issues between 3.9.0-beta and 3.9.1-rc so haven’t yet figured out which contributed the fix but thought I’d share what I’ve found so far.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating a Custom Element Decorator Using TypeScript
In the post I showed you how you can build your own TypeScript decorator in order to remove some of custom elements boilerplate...
Read more >
Regarding the broken promise of Web Components
Because a Custom Element is really just a class instance, you can (and should) provide a properties interface using ES6 class getters/setters.
Read more >
A Detailed Introduction To Custom Elements
Well, not me. That's quite an ambiguous description, so the point of this article is to explain what Custom Elements are for, why...
Read more >
Handling data with Web Components | by Andreas Remdt
Attributes are the easiest way to pass data into a custom element: ... In the above example, we create a new image element...
Read more >
Why I don't use web components - DEV Community ‍ ‍
Shadow DOM is my favorite part, despite its problems. Custom Elements are just interface for me. I get so much use out content...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found