Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript compilation issues #291

Open
arodidev opened this issue Oct 17, 2024 · 9 comments
Open

Typescript compilation issues #291

arodidev opened this issue Oct 17, 2024 · 9 comments
Labels

Comments

@arodidev
Copy link

I am getting some typescript issues that are a bit difficult to resolve when trying to override the components in the JSXParser components map prop. Sample code below:

<JSXParser
  components={{
    PieChart: (props: React.ComponentProps<typeof PieChart>) => (
      <ErrorBoundary FallbackComponent={ErrorFallback}>
        <PieChart
          {...(props as React.ComponentProps<typeof PieChart>)}
          container={
            CardComponent as React.ComponentType<ContainerComponentProps>
          }
        />
      </ErrorBoundary>
    ),    
  }}
  jsx={
    "<PieChart userOptions={{ dataLabels: { enabled: true }, stroke: { show: false } }} />"
  }
/>

I seem to be getting this error:

Type '(props: React.ComponentProps<typeof PieChart>) => JSX.Element' is not assignable to type 'ComponentType | ExoticComponent<{}>'

Is there a way to extend (or override) the types provided for the JSXParser component to fix these errors.

@TroyAlford
Copy link
Owner

TroyAlford commented Oct 21, 2024 via email

@arodidev
Copy link
Author

I'm running version 2.0.0 of react-jsx-parser and version 18.3.3 of react . Should bumping the version sort out the issue?

@TroyAlford
Copy link
Owner

TroyAlford commented Oct 21, 2024 via email

@arodidev
Copy link
Author

The problem still seems to persist

@AndreasBrostrom
Copy link

AndreasBrostrom commented Oct 25, 2024

I'am experiencing this as well.

ERROR in src/components/Comp.tsx:764:40
TS2769: No overload matches this call.
  Overload 1 of 2, '(props: TProps): JsxParser', gave the following error.
    Type '({ children, ...props }: LinkProps) => Element' is not assignable to type 'ComponentType<{}> | ExoticComponent<{}>'.
      Type '({ children, ...props }: LinkProps) => Element' is not assignable to type 'FunctionComponent<{}>'.
        Types of parameters '__0' and 'props' are incompatible.
          Property 'to' is missing in type '{}' but required in type 'LinkProps'.
  Overload 2 of 2, '(props: TProps, context: any): JsxParser', gave the following error.
    Type '({ children, ...props }: LinkProps) => Element' is not assignable to type 'ComponentType<{}> | ExoticComponent<{}>'.
  > 764 |   const jsx = <JsxParser components={{ Link }} jsx={text} />;
        |                                        ^^^^
    765 |   console.log(jsx);
    766 |   return jsx;
    767 | };

Here is some extract from my code how i have it setup. In case i misunderstood something about this.

import React from "react";
import { isMobile } from "react-device-detect";
import { Link as RouterLink } from "react-router-dom";
import { colorNormal } from "./Styling";
import JsxParser from "react-jsx-parser";

interface LinkProps {
  children?: React.ReactNode | string;
  tooltip?: string;
  to: string;
  style?: React.CSSProperties;
}
export function Link({ children, ...props }: LinkProps) {
  const useTooltip = !isMobile && props.tooltip;

  return (
    <>
      {useTooltip && <Tooltip id="linkTooltip" />}
      <RouterLink
        data-tooltip-id={useTooltip ? "linkTooltip" : undefined}
        data-tooltip-content={useTooltip ? props.tooltip : undefined}
        data-tooltip-place={useTooltip ? "top" : undefined}
        to={props.to}
        rel="noopener noreferrer"
        style={{
          color: colorNormal,
          ...props.style,
        }}
      >
        {children}
      </RouterLink>
    </>
  );
}

export const handleText = (text: string) => {
  const jsx = <JsxParser components={{ Link }} jsx={text} />;
  return jsx;
};

From a render function:

export default Character;
function Page() {
  const description = [
    "Nulla non mauris mauris. Mauris vel maximus turpis.",
    'Sed rutrum urna quis ligula <Link to="/somewhere/here">egestas<Link>, a gravida justo venenatis.',
    'Phasellus sed tempus enim. In non malesuada tortor, sed <Link to="/somewhere/other">ullamcorper massa<Link>.',
  ];
  return (
    <>
      {description ? (
        description.map((body) => (
          <Text key={"body"}>{handleText(description.toString())}</Text>
        ))
      ) : (
        <Text>No information given.</Text>
      )}
    </>
  );
}

@TroyAlford
Copy link
Owner

@AndreasBrostrom I'm not 100% sure — but I believe the issue is that your system is interpreting the output of your component as JSX.Element. This may simply be the TS interpretation of () => <div /> type syntax.

It may help for the lib to allow for that as an alternative signature for components, but in the meantime, can you please change your code to:

export const Link = React.FC<LinkProps>({ children, ...props }) => {

The React.FC may type-coerce your TS into understanding that it will output a React.ReactNode rather than a JSX.Element. An alternative would be to alter the return statement as something like:

return <>
  {/* all your stuff */}
</> as React.ReactNode

and see if that addresses the coersion?

Finally, you can easily get around this as a workaround by simply adding:

// @ts-expect-error - incorrectly inferred return type

Right above the offending line.

@TroyAlford
Copy link
Owner

I attempted to expand the allowable signatures for components in the version I just pushed. Please pull latest and let me know if this resolves?

@TroyAlford TroyAlford added the bug label Oct 30, 2024
@trevordixon
Copy link

trevordixon commented Dec 3, 2024

Same issue. Repro here: TS Playground

Could make the type React.ComponentType<any>, but users should probably just write their components with all props optional, because templates aren't type checked, so there's nothing to guarantee required props will be defined.

@ShahriarKh
Copy link

ShahriarKh commented Dec 13, 2024

Please pull latest and let me know if this resolves?

I tried with 2.2.2 and the issue still persists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants