Typescript+SolidJS:如何扩展某些 JSX 元素的道具?

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

我如何在某些现有 JSX 元素的 SolidJS 道具中扩展并创建我的自定义界面,例如下面给出的 React 示例中的 ButtonProps 界面。

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

我平时的做法是这样的:

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

我在示例中使用了类型交集,但您可以通过扩展接口来做同样的事情。

我在这里使用 Component 类型,默认情况下它还会向 props 添加一个可选的 children prop,尽管我认为这会随着 1.4 版本的发布而改变。

我还使用 splitProps 方法来帮助避免解构,以保留对 prop 值的反应性更新。

以非常相同的方式,除了您需要避免解构响应式属性并改用 splitProps,因此您的示例将转换为:

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

如您所见,内在元素属性的类型在 JSX 中,来自 jsx-dom-expressions 将 JSX 转换为实体中的反应式表达式。