pacote icon indicating copy to clipboard operation
pacote copied to clipboard

react-with-props: type-checking (error reporting) is "backwards"

Open mindplay-dk opened this issue 8 months ago • 2 comments

It seems the type-checking errors get reported against the wrong argument.

For example:

import { withDefaultProps } from '@pacote/react-with-props'

function Hello({ world }: { world?: string }) {
  return <div>Hello, {world}</div>;
}

const HelloWithDefaults = withDefaultProps({ world: 123 }, Hello);

In this example, the error gets reported against the second argument Hello, rather than against the 123 value incorrectly given for world.

Argument of type '({ className, world }: { className?: string | undefined; world?: string | undefined; }) => Element' is not assignable to parameter of type 'InnerComponent<{ world: number; }>'.
  Type '({ className, world }: { className?: string | undefined; world?: string | undefined; }) => Element' is not assignable to type 'FunctionComponent<{ world: number; }>'.
    Types of parameters '__0' and 'props' are incompatible.
      Type '{ world: number; }' is not assignable to type '{ className?: string | undefined; world?: string | undefined; }'.
        Types of property 'world' are incompatible.
          Type 'number' is not assignable to type 'string'.(2345)

I believe the component Hello should be treated as the source of the correct property types in this scenario?

We're setting defaults, so the default properties and types should match those of Hello, not the other way around?

Here's a sandbox showing what I was trying to do:

https://stackblitz.com/edit/vitejs-vite-hkxlq6wj?file=src%2FApp.tsx

Possibly related to #1 and/or #5

mindplay-dk avatar Mar 31 '25 13:03 mindplay-dk

I may be totally naive here, but is there any reason this wouldn't do it?

import type React from 'react';

function withDefaultProps<P>(
  defaultProps: Partial<P>,
  Component: React.ComponentType<P>
) {
  /* @ts-ignore */
  return (props: P) => <Component {...defaultProps} {...props} />;
}

This seems to correctly highlight errors just as I expected:

Image

Sandbox here: https://stackblitz.com/edit/vitejs-vite-zeiz57tq?file=src%2FApp.tsx&terminal=dev

I don't understand what all those complex types are for - isn't this enough? 🤷‍♂️😊

mindplay-dk avatar Mar 31 '25 14:03 mindplay-dk

Hi, thanks! I'll have to check, it's been a while since I did this, very likely the current implementation is overcomplicated.

goblindegook avatar Apr 05 '25 08:04 goblindegook