I cannot give too much information here (because there really isn't), but only this:
All of the sudden, after adding a @Method
function to a stencil component:
@Method()
async setMenuItems(items: Element[]): Promise<void> {
// code here
}
the component stopped compiling with the following - really unhelpful - error:
[ ERROR ] ./src/components/menu-content/menu-content.tsx:63:44
build error
L62: @Method()
L63: async setMenuItems(elements: Element[]): Promise<void> {
L64: const unsupportedChildren = elements.filter(e => !this.isSupportedChild(e)).map(e => e.tagName);
[12:37.1] build failed in 7.02 s
Promise<void>
inside the error-message is highlighted red@Method
s that do work within this component (even with the same return type).@Method
is structurally equal to those that do work.async
and add return Promise.resolve()
@Method
decorator (compiled, but of course my method is removed from API)node_modules
folder and reinstallI remember that I already had this error once, and apparently I somehow fixed it (or not, idk). But if I did, I cannot remember how.
Does anyone have an idea how to debug this - or even better fix?
I figured it out. A more complete version of my component is:
import { Element, ... } from '@stencil/core';
class MenuContent {
@Element() element: MenuContentElement;
@Method()
setMenuItems(elements: Element[]): Promise<void> {
// ------------------^^^^^^^
// Element is meant to be the built-in browser interface for Element
// but stencil thinks that this is the imported Element from '@stencil/core'!
}
}
The exact problem here is, that the stencil-compiler seems to assume that the elements
parameter is of type Element
that is imported from @stencil/core
which is obviously wrong and leads to this strange unhelpful error.
Element
type// types.ts
export type DomElement = Element;
// menu-content.tsx
import { DomElement } from './types';
...
async setMenuItems(elements: DomElement[]): Promise<void> { ... }
HTMLElement
Note: This is only legit, when you don't need to support other Element-types such as SVGElement
s for example!
async setMenuItems(elements: HTMLElement[]): Promise<void> { ... }
Please note: When using @stencil eslint rules, they will complain about your renamed import and say that "own class members are not allowed to be public".
I created a ticket for it here: https://github.com/ionic-team/stencil-eslint/issues/28
import { Element as ElementDecorator} from '@stencil/core';
class MenuContent {
// eslint will complain about that:
// "Own class properties cannot be public."
@ElementDecorator() element: HTMLMenuContentElement;
}