artcom / react-three-arjs

AR.js with react-three-fiber
174 stars 43 forks source link

Typescript support #6

Open aVileBroker opened 2 years ago

aVileBroker commented 2 years ago

Currently, using react-three-arjs is a bit frustrating in TS. The R3F Canvas needs to be imported (not used) to get the R3F JSX elements, and none of the components have the props accessible/defined. This codebase is pretty small so adding types should be fairly simple.

I'm happy to work on this and get a PR up for it if need-be!

j-era commented 2 years ago

Hi @aVileBroker, i'm not an TS expert, so I would be very happy if you could point this out with an example?

aVileBroker commented 2 years ago

Sure! Here's two screenshots - one with react-three-fiber importing something, and the other without. You can see that the Canvas isn't actually used, but it does enough to add the threejs primitives to the JSX primitive types. image image

aVileBroker commented 2 years ago

For the react-three-arjs specific type issues, obviously there are no type definitions so I have a lot // @ts-ignore lines to skip TS trying to check these components. It would be very helpful if the types were defined, though.

kalwalt commented 2 years ago

I think you could develop type definitions for react-three-arjs as described in this guide https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html but i never tried, so i can't assure that it's appliable in this case.

j-era commented 2 years ago

Added ts declarations in a separate branch. @aVileBroker Would be happy if you can test if it works like this.

aVileBroker commented 2 years ago

Sweet! I'll check it out, thank you!

kalwalt commented 2 years ago

@j-era @aVileBroker probably is better to move definitions in another folder and then add "types": "types/src/index.d.ts", in package.json or you should in anyway add that entry with "types": "src/index.d.ts",

j-era commented 2 years ago

Updated types in 951e6b9 Think it should work like this @aVileBroker Did you try?

georg-un commented 1 year ago

Is there any progress on this? Can I assist somehow?

loganknecht commented 1 year ago

Hello!

Love this project ❤️ !

Chiming in to say the typescript support would be awesome

Thanks for everything!

loganknecht commented 1 year ago

EDIT: It looks like the issue I'm experiencing is from #35

Not sure how to solve this.


I cannot get this library to work with typescript 😞

image

I have tried using a custom typings file that uses the above types provided My tsconfig.json

{
    "compilerOptions": {
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "isolatedModules": true,
        "jsx": "react-jsx",
        "lib": ["dom", "dom.iterable", "esnext"],
        "module": "esnext",
        "moduleResolution": "node",
        "noEmit": true,
        "noFallthroughCasesInSwitch": true,
        "resolveJsonModule": true,
        "skipLibCheck": true,
        "strict": true,
        "target": "es5",
        "typeRoots": ["src/custom_typings", "node_modules/@types"]
    },
    "include": ["src"]
}

The typincs file is in this location REPOSITORY_ROOT/src/custom_typings/artcom__react-three-arjs.d.ts

My type definitions

import { Props } from "@react-three/fiber/dist/declarations/src/web/Canvas";

declare module "@artcom/react-three-arjs" {
    export interface ARCanvasProps extends Props {
        arEnabled?: boolean;
        tracking?: boolean;
        patternRatio?: number;
        detectionMode?: string;
        cameraParametersUrl?: string;
        matrixCodeType?: string;
        sourceType?: string;
        onCameraStreamReady?: () => void;
        onCameraStreamError?: () => void;
    }

    export interface ARMarkerProps {
        children: React.ReactNode;
        type: string;
        barcodeValue?: string;
        patternUrl?: string;
        params?: Object;
        onMarkerFound?: () => void;
        onMarkerLost?: () => void;
    }

    export declare function ARCanvas(props: ARCanvasProps): JSX.Element;

    export declare function ARMarker(props: ARMarkerProps): JSX.Element;
}

But it just won't work.

I have tried other type definitions such as an ambient type declaration for the types of this library. None of the works.

@aVileBroker - Were you able to get this working? Has anyone been able to get this working?

bloodylupin commented 1 year ago

EDIT: It looks like the issue I'm experiencing is from #35

Not sure how to solve this.

I cannot get this library to work with typescript 😞

image

I have tried using a custom typings file that uses the above types provided My tsconfig.json

{
    "compilerOptions": {
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "isolatedModules": true,
        "jsx": "react-jsx",
        "lib": ["dom", "dom.iterable", "esnext"],
        "module": "esnext",
        "moduleResolution": "node",
        "noEmit": true,
        "noFallthroughCasesInSwitch": true,
        "resolveJsonModule": true,
        "skipLibCheck": true,
        "strict": true,
        "target": "es5",
        "typeRoots": ["src/custom_typings", "node_modules/@types"]
    },
    "include": ["src"]
}

The typincs file is in this location REPOSITORY_ROOT/src/custom_typings/artcom__react-three-arjs.d.ts

My type definitions

import { Props } from "@react-three/fiber/dist/declarations/src/web/Canvas";

declare module "@artcom/react-three-arjs" {
    export interface ARCanvasProps extends Props {
        arEnabled?: boolean;
        tracking?: boolean;
        patternRatio?: number;
        detectionMode?: string;
        cameraParametersUrl?: string;
        matrixCodeType?: string;
        sourceType?: string;
        onCameraStreamReady?: () => void;
        onCameraStreamError?: () => void;
    }

    export interface ARMarkerProps {
        children: React.ReactNode;
        type: string;
        barcodeValue?: string;
        patternUrl?: string;
        params?: Object;
        onMarkerFound?: () => void;
        onMarkerLost?: () => void;
    }

    export declare function ARCanvas(props: ARCanvasProps): JSX.Element;

    export declare function ARMarker(props: ARMarkerProps): JSX.Element;
}

But it just won't work.

I have tried other type definitions such as an ambient type declaration for the types of this library. None of the works.

@aVileBroker - Were you able to get this working? Has anyone been able to get this working?

Hola, I just started a project with Next and TS and today I wrote the d.ts file to make TS happy. Maybe I have a clue for you, did you try importing the Props after declaring the global module? That's my d.ts file and I have no more errors on IDE. Clearly if you don't need all the props or need more you can make them optional or add different ones

declare module "@artcom/react-three-arjs" {
  import { WebGLRenderer } from "three";
  import { CanvasProps } from "@react-three/fiber/dist/declarations/src/web/Canvas";
  declare const ARCanvas = ({
    children,
    camera,
    gl,
    onCreated,
    ...props
  }: {
    children: ReactNode;
    camera: { position: number[] };
    gl: {
      antialias: boolean;
      powerPreference: string;
      physicallyCorrectLights: boolean;
    };
    onCameraStreamReady: () => void;
    onCameraStreamError: () => void;
    onCreated: ({ gl }: { gl: WebGLRenderer }) => void;
  } & CanvasProps) => JSX.Element;
  declare const ARMarker = ({
    children,
    params,
    type,
    patternUrl,
  }: {
    children: ReactNode;
    params: { smooth: boolean };
    type: "barcode" | "hiro" | "pattern";
    patternUrl: string;
    onMarkerFound: () => void;
  }) => JSX.Element;
}

In addition to that I had some errors that went away dynamic importing the ArCanvas with ssr: false. Hope it helps, bye!