aframevr / aframe

:a: Web framework for building virtual reality experiences.
https://aframe.io/
MIT License
16.69k stars 3.98k forks source link

Custom elements not compatible with React + Typescript #4826

Open justin-hackin opened 3 years ago

justin-hackin commented 3 years ago

Description:

When using Typescript with React, custom elements cause typescript errors such as Property 'a-scene' does not exist on type 'JSX.IntrinsicElements'. Installing @types/aframe does not address the issue. The errors go away when one manually defines the IntrinsicElements using the technique outlined in https://github.com/Microsoft/TypeScript/issues/15449#issuecomment-385959396. This is a tedious process as all tags and attributes for each element used must be defined. Another way to address this is to isolate the elements into a separate file where typescript checking is disabled, also not optimal.

  "devDependencies": {
    "@types/aframe": "^1.0.3",
  },
  "dependencies": {
    "aframe": "^1.2.0",
  },

The DefinitelyTyped entry for @types/aframe links here but should this be logged on the DefinitelyTyped repo instead? I consider this a big DX factor for aframe so I'm posting here first.

dmarcos commented 3 years ago

I’m not familiar with Typescript. For usage questions I recommend the Slack and Discord and channels and https://stackoverflow.com/questions/tagged/aframe. Also notice you are in an old A-Frame version. Use 1.2.0

dmarcos commented 3 years ago

It’s perhaps more of a limitation on how React / Typescript handle custom HTML elements?

rajsite commented 3 years ago

I think there are potentially more issue than just types when using React with web components. The library @lit-labs/react could potentially be used to wrap web components as React components but I haven't tried it with aframe.

benallfree commented 2 years ago

@rajsite What issues are you referring to?

antoniohof commented 2 years ago

you probably should use something similar to Vue's Vue.config.ignoredElements = ['a-scene'] I don't see any problem on doing that

lba-ben commented 1 year ago

I am also seeing this issue. I am on React 18 and frame 1.3.0. The exact error is: TS2339: Property 'a-scene' does not exist on type 'JSX.IntrinsicElements'. Any suggestions?

dmarcos commented 1 year ago

I'm not familiar with react. Can ask around.

CodyJasonBennett commented 1 year ago

@types/react does not inherit types for custom elements -- they're hardcoded in https://github.com/DefinitelyTyped/DefinitelyTyped/blob/adc1b6dd3233c3478e0744c0112355b8e2b431a1/types/react/index.d.ts#L3143 (although this should be in @types/react-dom).

You can extend them as per https://github.com/microsoft/TypeScript/issues/15449#issuecomment-385959396 with your own types, however. We've ran into this with pmndrs/react-three-fiber since TypeScript assumes it's for the web, and recently were able to dynamically map types from three rather than hardcode them (see three-types.ts from https://github.com/pmndrs/react-three-fiber/pull/2465).

I'd expect the same thing to be applicable here. I'm happy to contribute a fix, although I'm unsure of how to do so while keeping @types/react as an optional dependency.

dmarcos commented 1 year ago

Thanks so much. Yeah it would be great to keep A-Frame and React decoupled.

jotatoledo commented 1 year ago

Seems like somebody already started an effort to create the corresponding jsx types. See here

cyrfer commented 1 year ago

I'm building a React/Typescript application that currently uses AFrame (v1.4.2). I was able to improve the DX with npm i -D types-aframe-react (as posted by @jotatoledo) as well as add a file to my package:

src/types/index.d.ts

// types/index.ts
export {};

declare interface AframeComponentProp {
  type: string
  default?: string | number | boolean
}

declare interface AframeComponent {
  schema?: Record<string, AframeComponentProp>
  init?: Function
  update?: Function
  tick?: Function
  remove?: Function
  pause?: Function
  play?: Function
}

declare global {
  interface Window {
    AFRAME: {
      registerComponent: (name: string, component: AframeComponent) => void
    };
  }
}

My concern with types-aframe-react is that I was not able to find a Github repo for it. I think it would be wonderful if the aframe community made a public repo that people could contribute to.