Home > Blockchain >  Type '{}' has no properties in common with type 'IntrinsicAttributes'
Type '{}' has no properties in common with type 'IntrinsicAttributes'

Time:01-06

I create a dynamic button (Comp) in React TypeScript. "Comp" can be a button, anchor, or Link (React Router). I got a problem with the type having no properties in common with the type 'IntrinsicAttributes'.

type ButtonProps = {
  href?: string;
  to?: string;

  children: ReactNode;
};

function Button(props: ButtonProps) {
  const { href, to, children } = props;

  let Comp = 'button';
  if (href) Comp = 'a';
  if (to) Comp = 'Link';

  const compProps = { 
    href,
    to,
  };

  return <Comp {...compProps}>{children}</Comp>;
}

Here is the problem:

Type '{ children: ReactNode; href: string | undefined; to: string | undefined; }' has no properties in common with type 'IntrinsicAttributes'.ts(2559).

I researched some pics in StackOverflow but it's not my case.

CodePudding user response:

If you want to pass elements as strings, you can use React.createElement for dynamic props with those elements.

Note that Link is not a standard HTML element, so we cannot pass it as a string like button and a.

import React, { ReactNode, ElementType } from 'react'
import { Link } from 'react-router-dom'

type ButtonProps = {
  href?: string;
  to?: string;

  children: ReactNode;
};

function Button(props: ButtonProps) {
  const { href, to, children } = props;

  let comp: ElementType | typeof Link = 'button';
  if (href) comp = 'a';
  if (to) comp = Link;

  const compProps = { 
    href,
    to,
  };

  return React.createElement(comp, compProps, children);
}

Playground

CodePudding user response:

You can't use a string as a JSX constructor: Comp is not a valid tag.

You can rewrite your code like so:

type ButtonProps = {
  href?: string;
  to?: string;

  children: ReactNode;
};

function Button(props: ButtonProps) {
  const { href, to, children } = props;

  if (href) return <a href={href}>{children}</a>;
  if (to) return <Link to={to}>{children}</Link>;
  return <button>{children}</button>;
}
  • Related