aframe icon indicating copy to clipboard operation
aframe copied to clipboard

Custom elements not compatible with React + Typescript

Open justin-hackin opened this issue 4 years ago • 11 comments

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.

justin-hackin avatar Mar 16 '21 17:03 justin-hackin

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 avatar Mar 16 '21 17:03 dmarcos

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

dmarcos avatar Mar 16 '21 17:03 dmarcos

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.

rajsite avatar May 04 '21 03:05 rajsite

@rajsite What issues are you referring to?

benallfree avatar Jan 22 '22 21:01 benallfree

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

antoniohof avatar Jan 22 '22 23:01 antoniohof

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?

lba-ben avatar Nov 18 '22 19:11 lba-ben

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

dmarcos avatar Nov 19 '22 03:11 dmarcos

@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.

CodyJasonBennett avatar Nov 19 '22 05:11 CodyJasonBennett

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

dmarcos avatar Nov 19 '22 06:11 dmarcos

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

jotatoledo avatar Dec 13 '22 14:12 jotatoledo

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.

cyrfer avatar May 28 '23 13:05 cyrfer