Typescript+SolidJS: how can I extend props of some JSX element?

4.5k Views Asked by At

How can I extend in SolidJS props of some existing JSX element and create my custom interface like this ButtonProps interface in the given below example for React.

import React from 'react';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  title: string;
  showIcon: boolean;
}

const Button: React.FC<ButtonProps> = ({ title, showIcon, ...props }) => {
  return (
    <button {...props}>
      {title}
      {showIcon && <Icon/>}
    </button>
  );
};
2

There are 2 best solutions below

0
On BEST ANSWER

In very much the same way, except you need to avoid destructuring for reactive properties and use splitProps instead, so your example would translate to:

import { splitProps, JSX } from 'solid-js';

interface ButtonProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
  title: string;
  // better make that optional, so you can use Button without having to
  // add the showIcon attribute:
  showIcon?: boolean;
}

const Button = (props: ButtonProps) => {
  const [local, buttonProps] = splitProps(props, ['title', 'showIcon']);
  return (
    <button {...buttonProps}>
      {local.title}
      {local.showIcon && <Icon/>}
    </button>
  );
};

As you can see, the types of the intrinsic element attributes are in JSX, coming from the jsx-dom-expressions that convert JSX to reactive expressions in solid.

2
On

The way I usually do it is like this:

import type { Component, JSX } from "solid-js";
import { splitProps } from "solid-js";

export type ButtonProps = {
  title: string;
  showIcon: boolean;
} & JSX.HTMLAttributes<HTMLButtonElement>;

const Button: Component<ButtonProps> = (props) => {
  const [, rest] = splitProps(props, ["title", "showIcon"]);
  return (
    <button {...rest}>
      {props.title}
      {props.showIcon && <Icon/>}
    </button>
  );
}

I used a type intersection in my example, but you could do the same thing by extending the interface.

I'm using the Component type here, which by default also adds an optional children prop to the props, though I think that is going to change with the 1.4 release.

I'm also using the splitProps method to help avoid destructuring, so as to preserve reactive updates to the prop values.