ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.59k stars 789 forks source link

StencilJS - TypeScript - "Cannot find name ..." when exporting an enum #1096

Closed napolev closed 4 years ago

napolev commented 6 years ago

Stencil version:

 @stencil/core@0.11.4

I'm submitting a:

[x] bug report [ ] feature request [ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior:

[ 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

Expected behavior:

[13:07.4]  dev server: http://localhost:3333/
[13:07.4]  build finished, watching for changes... in
           9.86 s

Steps to reproduce:

$ mkdir stencil-cannot-find-name
$ cd stencil-cannot-find-name
$ clone https://github.com/napolev/stencil-cannot-find-name .
$ npm i
$ npm start

Related code:

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',
}

Other information:

You can see the error I stated above on the following image:

enter image description here

Also, even before compiling with npm, on 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.

I asked for help on StackOverflow on the following thread:

https://stackoverflow.com/questions/52351620/stenciljs-typescript-cannot-find-name

where the user (with high reputation): Aluan Haddad recommended me to post this as an issue.

napolev commented 6 years ago

I just added another branch to my repository with name: workaround_using_export_type with a workaround using: export type Anchor = 'left' | 'center' | 'right'; which is not the ideal solution but at least allows you to be kind of strict on typing. Anyway, I would be very happy if you guys fix this issue at compilation time so I be able to do: export enum Anchor { ... } without any issues.

pseudoramble commented 6 years ago

I think this is related to this issue: https://github.com/ionic-team/stencil/issues/1002. I think it's a planned feature to allow bundling types within the Stencil app/dist bundles.

brion-fuller commented 5 years ago

Is there any update on this issue?

arjunyel commented 5 years ago

Does exporting the type/enum/etc from another file, not the component file, work? More info here https://stencil-worldwide.slack.com/archives/C9LTCKAN8/p1560514008122900

brion-fuller commented 5 years ago

Yeah this works for me.

arjunyel commented 5 years ago

A error message is going to be added to stencil so it will explain this at build time, @brion-fuller @napolev do you think this issue can be closed? Thank you for reporting!

brion-fuller commented 5 years ago

Yeah I think that would be a good solution. Is there a PR for it? I didn't see any

NKBelousov commented 4 years ago

Just got this error myself, is there other way except removing enum?

romulocintra commented 4 years ago

Did u tried update stencil and TS?

NKBelousov commented 4 years ago

Did u tried update stencil and TS?

Yes, I get the same error with these versions:

├─ @stencil/core@1.8.1
└─ typescript@3.7.2
arjunyel commented 4 years ago

You'll have to move the enum to a separate file and import it

NKBelousov commented 4 years ago

You'll have to move the enum to a separate file and import it

I have separate types.ts file, is that it?

adamdbradley commented 4 years ago

Would you be able to try with the 1.9.0 prerelease?

leegee commented 4 years ago

I'm seeing the same error message for untouched, auto-generated tests with "@stencil/core": "^1.12.2", and whatever version of TypeScript it installed. That is I get this error out of the box in watch mode as I edit code. Once the error appears, it only clears when the page is reloaded.

txbrown commented 4 years ago

this error happens because the enum or type is never added to components.d.ts autogenerated file. this file contains a namspace with type definitions (export namespace Components) and I believe you cannot add to it without manually importing the type into it. but because this is an auto generated file that is a bad idea to do so.

green3g commented 4 years ago

I think this is still happening, No? I have a custom class in one of my component folders, like this:

│   ├── components
│   │   ├── app-ocr
│   │   │   ├── app-ocr.css
│   │   │   ├── app-ocr.e2e.ts
│   │   │   ├── app-ocr.tsx
│   │   │   └── FileUpload.ts

But I get error:

[ ERROR ]  TypeScript: ./src/components.d.ts:15:20
           Cannot find name 'FileUpload'.

     L14:      "uploadError": string;
     L15:      "uploads": FileUpload[];
     L16:  }

Because the auto gen file components.d.ts is not importing the custom class. Any tips to resolving this? When I manually import it, the live reload automatically replaces the import.

 @stencil/core@1.12.2
spaceemotion commented 4 years ago

Can confirm with 1.17.3

niklaas commented 4 years ago

Please re-open the issue. I can confirm this in 1.17.3 too.

tarkant commented 4 years ago

Hello, I'm having the same issue with v2.0.3 and v2.0.1, I export an enum that I import in a component, the generated components.d.ts does not import the enum even if I have another enum in the same folder and it's working. Tried with the flag --no-cache but no luck. What's more interesting is that it just stopped working, I didn't update stencil or anything...

tarkant commented 4 years ago

Hello again,

So I wanted to report back on my findings because I fixed my issue and maybe it will help the team too! I was already using an enum called EditMode that was working on my web component, the new enum I created was MapStyle and was practically an exact copy of the old enum. The only difference was that in my web component, I had the following :

import { EditMode, MapStyle } from './../models';

export MyComponent {
    @Prop()
    public editmode?: EditMode;

    @Prop()
    public mapstyle = MapStyle.TERRAIN;
}

This was not working and the components.d.ts generated did not import the MapStyle enum.

Doing the following fixed the issue :

import { EditMode, MapStyle } from './../models';

export MyComponent {
    @Prop()
    public editmode?: EditMode;

    @Prop()
    public mapstyle?: MapStyle;

    public componentDidLoad(): void {
        this.mapstyle = MapStyle.TERRAIN;
    }
}

I have no idea why, I hope you guys can figure it out 😅.

spaceemotion commented 4 years ago

Tried out the "fix" by @tarkant on 1.17.3 - didn't work. Will try out with the latest 2.x release soon.

tarkant commented 4 years ago

@spaceemotion I'm on @stencil/core: 2.0.3 I hope you won't have issues upgrading and eventually fixing this issue. Cheers!

spaceemotion commented 4 years ago

@tarkant can't seem to get it to work with v2.1.0 - not sure what you did so it works, haha

lauradelarie commented 3 years ago

I'm still seeing this problem with the following code, but strangely it was solved by adding a type declaration to the 'fold' property before assigning the default: @Prop() fold: Fold = Fold.Vertical

// card-preview.data.ts

export enum Fold {
  Vertical = 'vertical',
  Horizontal = 'horizontal'
}

// card-preview.component.tsx

@Prop() fold = Fold.Vertical;
ansghof commented 2 years ago

@lauradelarie : Thanks for saving me a lot of time. That worked.