chakra-ui/polymorphic

Event type is lost when using `as` prop in React package

kris-ellery opened this issue ยท 2 comments

Hi there! Thank you for working on a robust polymorphic component package with forwardRef support. I've been following the recent updates, including addition of react-polymorphed types. I noticed the event type gets lost when using as prop. It works in react-polymorphed, but not here. I was wondering if thats expected or a known issue?

react-polymorphed

import React, { forwardRef } from 'react';
import type { PolyRefFunction } from 'react-polymorphed';

const polyForwardRef = forwardRef as PolyRefFunction;

const PolyComponent = polyForwardRef<'div', {}>((props, ref) => {
    const { as: As = 'div', ...rest } = props;
    return <As ref={ref} {...rest} />;
});

const App = () => {
    return (
        <>
            {/* ๐Ÿ™‚ event: React.MouseEvent<HTMLDivElement, MouseEvent> */}
            <PolyComponent onClick={(event) => console.log(event)} />
            {/* ๐Ÿ™‚ event: React.MouseEvent<HTMLAnchorElement, MouseEvent> */}
            <PolyComponent as="a" onClick={(event) => console.log(event)} />
        </>
    );
};

@polymorphic-factory/react

import React from 'react';
import { polymorphicFactory } from '@polymorphic-factory/react';

const poly = polymorphicFactory();

const App = () => {
    return (
        <>
            {/* ๐Ÿ™‚ event: React.MouseEvent<HTMLDivElement, MouseEvent> */}
            <poly.div onClick={(event) => console.log(event)} />
            {/* ๐Ÿ˜” event: any */}
            <poly.div as="a" onClick={(event) => console.log(event)} />
        </>
    );
};

Same happens when using forwardRef directly.

import React from 'react';
import { forwardRef } from '@polymorphic-factory/react';

const PolyComponent = forwardRef<'div', {}>((props, ref) => {
    const { as: As = 'div', ...rest } = props;
    return <As ref={ref} {...rest} />;
});

const App = () => {
    return (
        <>
            {/* ๐Ÿ™‚ event: React.MouseEvent<HTMLDivElement, MouseEvent> */}
            <PolyComponent onClick={(event) => console.log(event)} />
            {/* ๐Ÿ˜” event: any */}
            <PolyComponent as="a" onClick={(event) => console.log(event)} />
        </>
    );
};

Thanks for catching that and providing a good reproduction ๐Ÿ’–

When we remove the ElementType and narrow it to as?: Default, the event typings are correct again โœจ but another error appears when I try to declare a React component like this:

const MyComponent: ComponentWithAs<'div'> = (props) => <poly.div as="a" {...props} />
Types of property 'as' are incompatible.
  Type 'AsComponent | undefined' is not assignable to type '"div" | undefined'.
    Type 'AsComponent' is not assignable to type '"div" | undefined'.
      Type 'ElementType' is not assignable to type '"div" | undefined'.
        Type '"symbol"' is not assignable to type '"div"'.

See your PR Action as reference as well: https://github.com/chakra-ui/polymorphic/actions/runs/4613923890/jobs/8191534864?pr=340#step:4:36

Still investigating how to resolve this. If you have any ideas, kindly let me know :)