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

Sew*_*iec 5 typescript solid-js

我如何在 SolidJS 中扩展一些现有 JSX 元素的属性,并创建我的自定义界面,就像ButtonProps下面给出的 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>
  );
};
Run Code Online (Sandbox Code Playgroud)

Foo*_*dom 11

我通常这样做的方式是这样的:

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

我在示例中使用了类型交集,但您可以通过扩展接口来完成相同的操作。

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

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


小智 8

以非常相似的方式,除了您需要避免对反应性属性进行解构并使用 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>
  );
};
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,JSX 中的内在元素属性的类型来自于将 JSX 转换为 Solid 中的反应式表达式的 jsx-dom-expression。