5

I have the following project:

https://github.com/napolev/stencil-cannot-find-name

which contains the following two files:

custom-container.tsx

import { Component, Element, State } from '@stencil/core';

@Component({
    tag: 'custom-container',
    styleUrl: 'custom-container.scss',
})
export class WebComponent {
    @Element() el!: HTMLStencilElement;
    @State() label: String = '<empty>';
    componentDidLoad() {
        document.querySelector('.button_get_anchor').addEventListener('click', () => {
            let position = '<unset>';
            position = this.el.querySelector('custom-details').getDefaultKnobEPosition();
            this.label = position;
        });
    }
    render() {
        return [
            <div class="label">{this.label}</div>,
            <custom-details></custom-details>,
            <div>
                <button class="button_get_anchor">Get Anchor</button>
            </div>
        ];
    }
}

custom-details.tsx

import { Component, Method } from '@stencil/core';

@Component({
    tag: 'custom-details',
    styleUrl: 'custom-details.scss',
})
export class WebComponent {
    render() {
        return [
            <div class="details">This is the "custom-details"</div>
        ];
    }
    @Method()
    sayHelloWorldOnConsole() {
        console.log('Hello World!');
    }
    //*
    @Method()
    getDefaultKnobEPosition(): Anchor {
        return Anchor.Left;
    }
    //*/
}
export enum Anchor {
    Left = 'left',
    Center = 'center',
    Right = 'right',
}

My problem is: When I run:

$ npm start --es5

I get the following error:

[ ERROR ]  TypeScript: ./stencil-cannot-find-name/src/components.d.ts:66:39
           Cannot find name 'Anchor'.

     L65:  interface CustomDetails {
     L66:    'getDefaultKnobEPosition': () => Anchor;
     L67:    'sayHelloWorldOnConsole': () => void;

[21:56.0]  dev server: http://localhost:3333/
[21:56.0]  build failed, watching for changes... in
           15.59 s

as you can see on the following image:

enter image description here

Also, even before compiling with npm, on the Visual Studio Code I get notified about that issue, as you can see on the following image:

enter image description here

Here is the line that is causing the problem:

https://github.com/napolev/stencil-cannot-find-name/blob/master/src/components.d.ts#L66

where that file above is auto-generated, so I cannot modify it in order to fix the issue.

Any idea on how to solve this?

Thanks!

davidesp
  • 3,743
  • 10
  • 39
  • 77

2 Answers2

2

Putting Anchor in its own file solves the build problem:

/src/components/custom-details/Anchor.ts

export enum Anchor {
    Left = 'left',
    Center = 'center',
    Right = 'right',
}

/src/components/custom-details/custom-details.tsx

import { Component, Method } from '@stencil/core';
import { Anchor } from './Anchor';

@Component({
    tag: 'custom-details',
    styleUrl: 'custom-details.scss',
})
export class WebComponent {
    render() {
        return [
            <div class="details">This is the "custom-details"</div>
        ];
    }
    @Method()
    sayHelloWorldOnConsole() {
        console.log('Hello World!');
    }
    //*
    @Method()
    getDefaultKnobEPosition(): Anchor {
        return Anchor.Left;
    }
    //*/
}
Thomas
  • 8,426
  • 1
  • 25
  • 49
  • Happy to help. Unfortunately I still have problems using those enums in an external application (in my case in an Angular app with Ionic 4). – Thomas Sep 24 '18 at 09:07
1

If the file is auto-generated, you are basically screwed. The only way that components.d.ts file can typecheck is if it has access to Anchor by importing it as in

import {Anchor} from './custom-details';

You could make it TypeCheck by injecting Anchor into the global scope, thereby making it visible to all of files in your compilation context

custom-details.tsx

export class WebComponent {
   // ....
}

declare global {
  enum Anchor {
    Left = 'left',
    Center = 'center',
    Right = 'right'
  }
}

(<{Anchor: typeof Anchor}>window.Stencil).Anchor = {
  Left = 'left',
  Center = 'center',
  Right = 'right'
};

But you really, really don't want to do this!

This pollutes the global namespace with a type and, infinitely worse, with a value!

File a bug report.

Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84
  • thanks @Aluan. One question, did you try running the application on you end? I think there should be a normal approach for this, since what I want to do is something very usual. – davidesp Sep 16 '18 at 07:42
  • Well, I didn't clone the repo, but I used the code you posted and installed `@stencil/core`. You are mistaken in stating that scenario is usual. The very usual approach thing is relative. If a framework generates files from your sources, it needs to parse those sources and import all exported symbols that the generated code references. Otherwise, the code generator has a bug or is not usable with module source files – Aluan Haddad Sep 16 '18 at 07:51
  • 1
    Ok Aluan, just posted this as an issue on: https://github.com/ionic-team/stencil/issues/1096, let's see if there is luck on this. Thanks! – davidesp Sep 16 '18 at 08:28