kripod / kripod/react-polymorphic-types

Incorrect work with Unions Types

Open
#1 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
197
Forks
9
PR merge metrics
No merged PRs in 30d

Description

## Description

Polymorphic component has partialized props if "as" component has unioned props.

## Reproduction

```
import * as React from 'react';
import type {
PolymorphicForwardRefExoticComponent,
PolymorphicPropsWithoutRef,
PolymorphicPropsWithRef,
} from 'react-polymorphic-types';

export const HeadingDefaultElement = 'h2';

export type HeadingOwnProps = {
color?: string;
};

export type HeadingProps<
T extends React.ElementType = typeof HeadingDefaultElement
> = PolymorphicPropsWithRef;

export const Heading: PolymorphicForwardRefExoticComponent<
HeadingOwnProps,
typeof HeadingDefaultElement
> = React.forwardRef(function Heading<
T extends React.ElementType = typeof HeadingDefaultElement
>(
{
as,
color,
style,
...restProps
}: PolymorphicPropsWithoutRef,
ref: React.ForwardedRef>
) {
const Element: React.ElementType = as || HeadingDefaultElement;
return ;
});

interface ITestA {
value: 'a';
}

interface ITestB {
value: 'b';
extra: string;
}

type Test = ITestA | ITestB;

const Test: React.FC = (props) => {
return <>;
};

function App() {
return (
<>



);
}

```

## Expected behavior

Polymorphic component has correct props types.

## Actual behavior

>`Type '{ as: FC; value: "b"; extra: string; }' is not assignable to type 'IntrinsicAttributes & Pick, "children" | "value"> & HeadingOwnProps & { ...; }'.
Property 'extra' does not exist on type 'IntrinsicAttributes & Pick, "children" | "value"> & HeadingOwnProps & { ...; }'.ts(2322)`

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the definitions of PolymorphicPropsWithoutRef, PolymorphicPropsWithRef, and PolymorphicForwardRefExoticComponent used in the reproduction, then recreate the Heading and union-prop example in a TypeScript check. Done means a polymorphic component accepting as={Test} also accepts the union member's extra prop without breaking the existing prop types.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.