Unleashing the Power of Typescript and SolidJS: Expanding the Properties of JSX Elements

Is there a way to enhance the props of an existing JSX element in SolidJS and craft a custom interface similar to the ButtonProps interface shown in this React example below?

import Solid from 'solid-js';

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

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

Answer №1

This has been my go-to approach:

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>
  );
}

In the example above, I utilized a type intersection, but an alternative method could involve extending the interface.

Within this code snippet, I've made use of the Component type, which currently includes an optional children prop in the props. However, this is slated to change with the upcoming 1.4 release.

Furthermore, I've incorporated the splitProps function to prevent destructuring and maintain reactive updates to the prop values.

Answer №2

Similarly, the method to achieve this is quite comparable, with the exception of refraining from destructuring for reactive properties and using splitProps instead. For instance, your code snippet would now look like:

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

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

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

It's worth noting that the attributes' types for intrinsic elements are within the realm of JSX in solid, courtesy of jsx-dom-expressions responsible for converting JSX into reactive expressions.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to utilize pinia getter as the initial parameter in Vue3's watch function?

Issue Recap In Vue3, can Pinia getters be utilized as a watch target's first argument? System Details Vue version: 3.2.13 Pinia version: 2.1.4 TypeScript version: 4.5.5 Problem Description An error was encountered when attempting to reference the ...

Utilize Angular to initiate the transmission of attribute values upon a click event

My question may be simple, but I've been struggling to find an answer. How can I send attributes or item property bindings of an item through a click event in the best way? For example: <item class="item" [attr.data-itemid]="item.id ...

Introducing the concept of type-specific name inclusion

I am currently developing my Angular app using TypeScript with the goal of preventing redundancy through some form of generic handling. Here is where I am starting: class BaseProvider { api_url = 'http://localhost:80/api/FILL_OUT_PATH/:id&apo ...

Using class-validator in Node.js to validate arrays of objects

My goal is to verify the Alcohol ID and Alcohol Name for emptiness. Below is the format I am working with: { "barId": "string", "barName": "string", "drinksItems": [ { "alcoholId": "string", "alcoholName": "string", "mixerLis ...

An issue has occurred while utilizing Angular

I'm diving into the world of Angular and encountering some errors as I try to execute this code. An unexpected token is causing trouble. A constructor, method, accessor, or property was expected. The left side of a comma operator seems to be unused ...

How can the file system module (fs) be utilized in Angular 7?

Hello, I am currently working with Angular 7. I recently attempted to utilize the fs module in Typescript to open a directory. However, I encountered an error message stating: "Module not found: Error: Can't resolve fs". Despite having types@node and ...

Enumerate the names of the private properties within the class

I am working on a problem where I need to use some of the class properties as values in a map within the class. In the example below, I have used an array instead of a map because when a property is marked private, it is not included in the keyof list. How ...

Issue: Unable to load the file named 'script.ts' while employing chrome.scripting.executeScript

Currently, I am working on developing a chrome extension using Vite with React and Typescript along with CRXJS. This is my initial project in this domain. The issue I am encountering is related to executing a script on the current tab when a button is clic ...

Restrictive discriminated union via function argument

I am in possession of a shop that organizes a variety of types based on their IDs interface Dog { type: "dog"; woofs: string; } interface Cat { type: "cat"; meows: string; } type Pet = Dog | Cat; type AnimalState = Record<string, Pet ...

Improved ergonomics for enhancing TypeScript union-narrowing typeguard function

Within our codebase, we have a utility that generates a typeguard to narrow down a discriminated union: export type ExtractBranchFromUnion< UNION, DISCRIMINANT extends keyof UNION, BRANCH extends UNION[DISCRIMINANT], > = UNION extends Record< ...

I am facing a problem with the code for my React login page and router

My form page is built in react and typescript, utilizing JWT tokens on the API side. While there are no issues with the container page, I encountered an error on the index.tsx page where the routers are defined: A TypeScript error occurred in C:/Users/yusu ...

Oops! The last loader did not provide a Buffer or String as expected

After converting my GraphQL query and HOC component to typescript, I encountered the following error: ERROR in ./client/components/Protected.Route.tsx Module build failed: Error: Final loader (./node_modules/awesome-typescript-loader/dist/entry.js) didn ...

Error: Class cannot be loaded by React Webpack loader

I'm encountering an issue with my two typescript packages - a React application and an infrastructure package. The React app has a dependency on the infrastructure package (currently linked via npm). After adding a new class to the infrastructure pack ...

Angular 5 Directive for Structuring Content

I'm currently in the process of developing a versatile search box component, with the following setup: search.component.html <div class="search-box-container"> <fa-icon class="search-icon" [icon]="faSearch"></fa-icon> <input ...

Simple and quickest method for incorporating jQuery into Angular 2/4

Effective ways to combine jQuery and Angular? Simple steps for integrating jQuery in Angular2 TypeScript apps? Not sure if this approach is secure, but it can definitely be beneficial. Quite intriguing. ...

How can nested json be sorted effectively based on two specific fields?

Example Data: [{ 'ID': objID(abc123), 'Department': 'IT', 'Employees': [ { 'ID': 3, 'StartDate': '24-12-2022T08:30', 'active': true }, { ...

Issue: The last loader (./node_modules/awesome-typescript-loader/dist/entry.js) failed to provide a Buffer or String

This issue arises during the dockerhub build process in the dockerfile. Error: The final loader (./node_modules/awesome-typescript-loader/dist/entry.js) did not return a Buffer or String. I have explored various solutions online, but none of them have pr ...

The pipe property cannot be accessed for the specified type "OperatorFunction<unknown, [unknown, boolean, any]>"

I have set up a data subscription that I want to utilize through piping, but for some reason it's not working as expected. The error message I'm receiving is: The property pipe is not available for type "OperatorFunction<unknown, [unknown, b ...

What is causing this issue in TypeScript version 4.8?

After updating to TypeScript 4.8 in VSCode, I have encountered an error in one of my React projects that was not present before. Strangely, this error does not prevent the code from compiling successfully when building the project. It's challenging to ...

Angular integration problem with aws-amplify when signing up with Google account

I am attempting to integrate AWS-Amplify(^4.3.0) with angular-12 and typescript (4.3.5). I have followed the documentation to configure amplify properly, but when trying to start the app, I encountered some amplify errors as shown below. Warning: D:\G ...