Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSX.IntrinsicElements error with typescript and react #1090

Closed
ywwu1 opened this issue Sep 13, 2018 · 18 comments
Assignees
Labels

Comments

@ywwu1
Copy link

@ywwu1 ywwu1 commented Sep 13, 2018

Stencil version:

@stencil/core@0.12.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:

I upgrade to version @stencil/core@0.12.4, the latest typescript, react, react-dom, and associated typings. After building the stencil component in it's own repo I imported the component using defineCustomElements, however typescript is throwing an error Property 'hello-world' does not exist on type 'JSX.IntrinsicElements' when I try to start the project.

Expected behavior:

There should be no errors.

Steps to reproduce:

I have created a repo demonstrating the bug, here.
https://github.com/ywwu1/__stencil-react-typescript-jsx-issue

The stencil component is located here.
https://github.com/ywwu1/hello-world

@ionitron-bot ionitron-bot bot added the triage label Sep 13, 2018
@hartjus

This comment has been minimized.

Copy link

@hartjus hartjus commented Sep 26, 2018

I'm running into this issue as well. I noticed that the typings for JSX in Typescript were removed in 0.12.4. Is there a recommended way to integrate built stencil components into a react/typescript application? Do I need to author my own d.ts to get around the compile errors?

@cbyte

This comment has been minimized.

Copy link

@cbyte cbyte commented Oct 17, 2018

Same problem here. I created manually an components.d.ts in the root folder of the project to define the element declarations by hand. This is not a good solution overall, but works for the moment.

Now i step into the problem, how to include multiple compiled packages, because defineCustomElements() cannot be called multiple times - it throws the error Uncaught (in promise) TypeError: Cannot redefine property: queue.

Here is the self defined component.d.ts as temporarily solution to include one compiled stencil package:

import { Components } from "@ionic/core";

declare global {
  namespace JSX {
    interface IntrinsicElements {
       [...]
      "ion-toggle": Components.IonToggleAttributes;
      "ion-toolbar": Components.IonToolbarAttributes;
      "ion-virtual-scroll": Components.IonVirtualScrollAttributes;
    }
  }
}
@lcgreen

This comment has been minimized.

Copy link

@lcgreen lcgreen commented Oct 23, 2018

Also experiencing the same issue, is there no update on this? Authoring our own components.d.ts is not a solution.

@Dohxis

This comment has been minimized.

Copy link

@Dohxis Dohxis commented Oct 28, 2018

We are experiencing this as well.

@maraisr

This comment has been minimized.

Copy link

@maraisr maraisr commented Oct 28, 2018

Bumping +1

@arjunyel

This comment has been minimized.

Copy link
Collaborator

@arjunyel arjunyel commented Nov 12, 2018

Anyone have a workaround?

@Dohxis

This comment has been minimized.

Copy link

@Dohxis Dohxis commented Nov 12, 2018

Right now we maintain our own types.d.ts file as suggested by @cbyte.

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Nov 15, 2018

I found the same error when I was updating my library :( If you see something... I'll appreciate your help.

Hi,

I take the comment to put here something has worked for me. I removed the components.d.ts file, and the node_modules folder, after it, I installed the packages again with yarn, and the problem was solved.

Now, the components.d.ts file autogenerated has this.

  export namespace JSX {
    export interface Element {}
    export interface IntrinsicElements extends StencilIntrinsicElements {
      [tagName: string]: any;
    }
  }

I hope it works for you also.

Thanks! :)

@alex-hall

This comment has been minimized.

Copy link

@alex-hall alex-hall commented Jan 16, 2019

Any movement on this?

Have gone with the following hack for now:

//jsx-interfaces.d.ts
declare namespace JSX {
    interface IntrinsicElements {
        [tagName:string]: any
    }
}

Which basically just turns off Typescript JSX validation. NOTE: I do NOT like this solution.

I feel like i'm missing something obvious here, as all of the types are seemingly defined in:

<my_stencil_component>/dist/types/components.d.ts

But I can't seem to get create-react-app to recognize them or import them.

@hartjus

This comment has been minimized.

Copy link

@hartjus hartjus commented Jan 16, 2019

@alex-hall We ended up having to author (actually generate) our own d.ts for any stencil components that we pulled into our project. Stencil is generating most of the type definitions required, however there's the last step of adding the JSX tag into the global definitions.

Here's the basic structure of what we generated:

import {Components as SomeOtherName} from 'your-stencil-component';

declare global {
    namespace JSX {
        export interface IntrinsicElements {
            'your-component-tag': SomeOtherName.YourComponentAttributes;
        }
    }
}

While this works, it's definitely not ideal.

@alex-hall

This comment has been minimized.

Copy link

@alex-hall alex-hall commented Jan 16, 2019

Gotcha, Thanks for the quick response.

I felt like I was doing the right thing but nothing was working. Your explanation makes a lot of sense.

@alex-hall

This comment has been minimized.

Copy link

@alex-hall alex-hall commented Jan 16, 2019

Now i'm considering a PR :)

async function generateComponentTypesFile(config: d.Config, compilerCtx: d.CompilerCtx, metadata: d.ModuleFile[], destination: string) {

The information looks to be correctly generated in the original source, it just never makes it into the bundled version:

//src/components.d.ts
  export namespace JSX {
    export interface Element {}
    export interface IntrinsicElements extends StencilIntrinsicElements {
      [tagName: string]: any;
    }
  }
  export interface HTMLAttributes extends StencilHTMLAttributes {}
@SimoneIrato

This comment has been minimized.

Copy link

@SimoneIrato SimoneIrato commented Mar 21, 2019

Did anybody find a solution for this problem? Actually when using StencilJs in a monorepo, JSX typings from Stencil conflicts with those from React

@manucorporat

This comment has been minimized.

Copy link
Member

@manucorporat manucorporat commented Mar 28, 2019

Upcoming version of stencil will completely solve this problem by using locally scoped JSX namespaces, a new feature of typescript!

@vidarc

This comment has been minimized.

Copy link
Contributor

@vidarc vidarc commented Apr 5, 2019

@manucorporat has that made it in stencil/core version 1 yet? i'm currently using alpha 5, but not really seeing a way to get the typing in my react project to work. i can easily just ignore it by using one of the examples above and basically setting the component to an any type. would certainly prefer to not do that.

using any of my stencil components, like <ma-icon>, just gives the Property 'ma-icon' does not exist on type 'JSX.IntrinsicElements'. error

@manucorporat

This comment has been minimized.

Copy link
Member

@manucorporat manucorporat commented Apr 29, 2019

Stencil one uses locally scoped JSX, which is the final solution to the root of the problem, global styles conflicting with each other

@nireak

This comment has been minimized.

Copy link

@nireak nireak commented May 27, 2019

I still have the same error when using, inside a CRA 3.0 typescript react app, a webcomponent ("vertical-fields") created with "@stencil/core": "^1.0.0-beta.5"

Within the main "index.tsx" I'm loading the definitions with

...
import { defineCustomElements } from 'mywebcomponent/dist/loader'
...
defineCustomElements(window)

the file at node_modules/mywebcomponent/dist/types/components.d.ts seems to use locally scoped JSX

import { HTMLStencilElement, JSXBase } from './stencil.core';


export namespace Components {
  interface VerticalFields {
    'colorvorh': string;
    'levels': number;
  }
}

declare namespace LocalJSX {
  interface VerticalFields extends JSXBase.HTMLAttributes {
    'colorvorh'?: string;
    'levels'?: number;
  }
  interface IntrinsicElements {
    'vertical-fields': VerticalFields;
  }
}
export { LocalJSX as JSX };
declare module "@stencil/core" {
  export namespace JSX {
    interface IntrinsicElements extends LocalJSX.IntrinsicElements {}
  }
}
declare global {
  interface HTMLVerticalFieldsElement extends Components.VerticalFields, HTMLStencilElement {}
  var HTMLVerticalFieldsElement: {
    prototype: HTMLVerticalFieldsElement;
    new (): HTMLVerticalFieldsElement;
  };
  interface HTMLElementTagNameMap {
    'vertical-fields': HTMLVerticalFieldsElement;
  }
  interface ElementTagNameMap extends HTMLElementTagNameMap {}
}

Any ideas? Thank you

@Nibblesh

This comment has been minimized.

Copy link

@Nibblesh Nibblesh commented Jun 12, 2019

for people struggling with this, I've gotten things working this way

// register-web-components.ts
/* eslint-disable */
import { defineCustomElements, JSX as LocalJSX } from 'stencil-library/dist/loader';
import { HTMLAttributes } from 'react';

type StencilToReact<T> = {
  [P in keyof T]?: T[P] & Omit<HTMLAttributes<Element>, 'className'> & {
    class?: string;
  };
} ;

declare global {
  export namespace JSX {
    interface IntrinsicElements extends StencilToReact<LocalJSX.IntrinsicElements> {
    }
  }
}

defineCustomElements(window)
// index.ts
// ...
import './register-web-components';
// ...

eslint will shout about using declare global but this is keeping me going for now. gets auto complete working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.