react-pdf
react-pdf copied to clipboard
Throwing Error in React 18
Describe the bug Using the package in react 18 is giving the error of children not mentioned in the props
To Reproduce Steps to reproduce the behavior including code snippet (if applies):
- Create a Sample File using React 18
- Try to Run the app
- See error
'(props: DocumentProps | Readonly<DocumentProps>): Document', gave the following error. Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes<Document> & Readonly<DocumentProps>'. Overload 2 of 2, '(props: DocumentProps, context: any): Document', gave the following error. Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes<Document> & Readonly<DocumentProps>'.ts(2769)
@diegomura
I belive in react 18 you need to explicitly define the children props https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
same issue here, how do you solved it with child props? or is it still ongoing?
same issue here, how do you solved it with child props? or is it still ongoing?
Its still ongoing , i am trying every possible way to at least patch it, so it can work until a proper fix is out , Will post if i found anything
if you want to use React18 , i use my little dirty helper this work, renaming helps to trick Typescript
import { Document, Page, Text, View, StyleSheet } from '@react-pdf/renderer';
// rename helper for react18 overload
const MyDocument: any = Document
const MyPage: any = Page
// example code
const PDF= () => (
<MyDocument>
<MyPage="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #1</Text>
</View>
<View style={styles.section}>
<Text>Section #2</Text>
</View>
</MyPage>
</MyDocument>
if you want to use React18 , i use my little dirty helper this work, renaming helps to trick Typescript
// rename helper for react18 overload const MyDocument: any = Document const MyPage: any = Page // example code const PDF= () => ( <MyDocument> <MyPage="A4" style={styles.page}> <View style={styles.section}> <Text>Section #1</Text> </View> <View style={styles.section}> <Text>Section #2</Text> </View> </MyPage> </MyDocument>
Thank you very much , for the code
I faced the same problem with react 17, the solution presented by @RiJung is definitely super, here is an enhancement that does not lose the type checking as much as possible
import {
Document as PdfDocument,
Page as PdfPage,
Text,
View
} from '@react-pdf/renderer';
import React, {
ClassType,
Component,
ComponentClass,
ComponentProps,
HTMLProps,
ReactNode
} from 'react';
// I renamed `Page` to `PdfPage` on import, and here assigning itto a variable named `Page`
// so that the code here is aligned with `react-pdf` documentation examples,
// same goes with `Document` import.
const Page: ClassType<
ComponentProps<typeof PdfPage> & { children?: ReactNode },
Component<ComponentProps<typeof PdfPage> & { children?: ReactNode }>,
ComponentClass<ComponentProps<typeof PdfPage> & { children?: ReactNode }>
> = PdfPage as any;
const Document: ClassType<
ComponentProps<typeof PdfDocument> & {
children: ReactNode;
},
Component<
ComponentProps<typeof PdfDocument> & {
children: ReactNode;
}
>,
ComponentClass<
ComponentProps<typeof PdfDocument> & {
children: ReactNode;
}
>
> = PdfDocument as any;
export function Pdf(props: HTMLProps<HTMLDivElement>) {
return (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #1</Text>
</View>
<View style={styles.section}>
<Text>Section #2</Text>
</View>
</Page>
</Document>
);
}
Thanks for the workaround @RiJung Is there though a proper solution for this other than waiting for a new version of react-pdf? Will this be resolved in a future update?
I still have issues with ReactPDF.Styles. "TS2559 Type string has not properites in common with type 'Style'" - But the workaround seems to work for the moment. (thx a lot hahouari)
Somehow there was/is also a change in ReactPDF.Styles
so that this is not working anymore
export const styles = StyleSheet.create({ ...
But thats probably because of the uprade and I'll take a look at it tomorrow.
While waiting for an update. This should be a nicer solution to preserve TS definitions:
import React, { ReactNode } from "react";
import {
Page as _Page,
Document as _Document,
} from "@react-pdf/renderer";
function componentWithChildren<Props>(Component: React.ComponentType<Props>) {
return Component as React.ComponentType<Props & { children: ReactNode }>;
}
const Document = componentWithChildren(_Document);
const Page = componentWithChildren(_Page);
const Template = () => (
<Document>
<Page>
// Children go here
</Page>
</Document>
)
Then you can keep using Document
, Page
, Svg
, and possibly other react components that until react 18 used an implicit children prop.
Here is some info on the @types/react 18 upgrade and the breaking change related to the children
prop:
https://solverfox.dev/writing/no-implicit-children/
if you want to use React18 , i use my little dirty helper this work, renaming helps to trick Typescript
import { Document, Page, Text, View, StyleSheet } from '@react-pdf/renderer'; // rename helper for react18 overload const MyDocument: any = Document const MyPage: any = Page // example code const PDF= () => ( <MyDocument> <MyPage="A4" style={styles.page}> <View style={styles.section}> <Text>Section #1</Text> </View> <View style={styles.section}> <Text>Section #2</Text> </View> </MyPage> </MyDocument>
this worked like a charm, thank you!
Using the above workaround still ended up with an error in my project:
src/components/profile/download-pdf-modal/company-pdf/company-pdf.tsx:101:10 - error TS2352: Conversion of type 'ComponentType<Props>' to type 'ComponentType<Props & { children: ReactNode; }>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Type 'FunctionComponent<Props>' is not comparable to type 'ComponentType<Props & { children: ReactNode; }>'.
Type 'FunctionComponent<Props>' is not comparable to type 'FunctionComponent<Props & { children: ReactNode; }>'.
Types of property 'propTypes' are incompatible.
Type 'WeakValidationMap<Props>' is not comparable to type 'WeakValidationMap<Props & { children: ReactNode; }>'.
Type 'null extends Props[K] ? Validator<Props[K]> : undefined extends Props[K] ? Validator<Props[K]> : Validator<Props[K]>' is not comparable to type 'null extends (Props & { children: ReactNode; })[K] ? Validator<(Props & { children: ReactNode; })[K]> : undefined extends (Props & { children: ReactNode; })[K] ? Validator<...> : Validator<...>'.
Type 'Validator<Props[K]> | (undefined extends Props[K] ? Validator<Props[K]> : Validator<Props[K]>)' is not comparable to type 'null extends (Props & { children: ReactNode; })[K] ? Validator<(Props & { children: ReactNode; })[K]> : undefined extends (Props & { children: ReactNode; })[K] ? Validator<...> : Validator<...>'.
Type 'undefined extends Props[K] ? Validator<Props[K]> : Validator<Props[K]>' is not comparable to type 'null extends (Props & { children: ReactNode; })[K] ? Validator<(Props & { children: ReactNode; })[K]> : undefined extends (Props & { children: ReactNode; })[K] ? Validator<...> : Validator<...>'.
Type 'Validator<Props[K]>' is not comparable to type 'null extends (Props & { children: ReactNode; })[K] ? Validator<(Props & { children: ReactNode; })[K]> : undefined extends (Props & { children: ReactNode; })[K] ? Validator<...> : Validator<...>'.
101 return Component as React.ComponentType<Props & { children: ReactNode }>;
We were able to fix it by changing the componentWithChildren
function to this:
function componentWithChildren<Props>(Component: React.ComponentType<Props>) {
return Component as unknown as React.ComponentType<
Props & { children: ReactNode }
>;
}
But this doesn't seem ideal, and I'm not sure why its working for others and not us. These are the package versions we're on:
"@react-pdf/renderer": "^2.1.1",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"@types/node": "^17.0.34",
"@types/react": "^18.0.9",
"typescript": "^4.6.4"
If anyone has any insight, I'm definitely curious.
Does anyone know when it will be compatible with React 18?
Add those lines to a d.ts file fix the error for now :
declare module '@react-pdf/renderer' {
export { Circle, G, Path } from '@react-pdf/renderer';
export class Svg extends React.Component<React.PropsWithChildren<SVGProps>> {}
}
should be fixed in v3.1.1