kirillzyusko/react-native-bundle-splitter

Seems to be returning Typescript type for generic component, not imported component

matt-dalton opened this issue · 5 comments

Describe the bug
I just upgraded from v1 to v2.2.1, and I'm now getting Typescript errors. I guess the types might have broken, or this bug was concealed before (with any perhaps).

when I use register to load a component, it seems to just set the component type to React.ComponentClass<{}, any>, rather than the type of the component:
Screenshot 2022-10-27 at 15 10 36

This means I then get Typescript errors when I try and use the component, e.g.

Type '{ bottomBorder: true; leftIconOverride: Element; actionIcons: Element[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, any, any>> & Readonly<{}> & Readonly<{ children?: ReactNode; }>'.
  Property 'bottomBorder' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, any, any>> & Readonly<{}> & Readonly<{ children?: ReactNode; }>'.

253                         bottomBorder

Code snippet

const NavigationHeader = register({
    loader: () => require('Components/Header/Navigation/NavigationHeader'),
    group: HOME_SECONDARY_SCREENS,
})

//...

    <RootCardStack.Screen
        name="MyScreen"
        key="MyScreen"
        component={MyScreen}
        options={{
            header: (props: StackHeaderProps) => {
                return (
                    <NavigationHeader
                        bottomBorder
                        leftIconOverride={<BackButton />}
                    />
                )
            },
        }}
    />,

Expected behavior
I would expect the types of the actual component to be returned

Screenshots
If applicable, add screenshots to help explain your problem.

Smartphone (please complete the following information):

  • React Native 0.66
  • Typescript 4.8.4

Ahh I've seen we can import the types (from a separate file) and pass into a generic: const NavigationHeader = register<NavigationHeaderProps>(

Perhaps worth making more obvious in the docs? Unless I missed it somewhere

Hi @matt-dalton

Yes, you are right, it was changed in v2.

The motivation why I decided to make it in this way you can find here

If you want to have a backward compatibility with v1, then I think you can simply use it like:

export default register<any>({ loader: () => import('./MyComponent') });

In v2 register function receives generic type T which has {} value by default. So you can specify which props your component expects to receive.

Perhaps worth making more obvious in the docs?

@matt-dalton Yes, good idea 👍
Do you know a good place (in already existing pages) for that to make it more obvious?

And what info in this doc should be?

I went to check if I'd done something wrong here, so could maybe just add a Typescript section at the bottom?

But yeah...all makes sense! Thanks.

@matt-dalton I will try to add it. I want to migrate documentation to Docusaurus v2 and use github workflow for docs publishing, because right now I do everything manually.
So yeah, good point! I will try to add it and re-work documentation in the future! :)