繁体   English   中英

扩展 typescript 中的 react-select 接口属性

[英]To extend the react-select interface property in typescript

我为我的 react-project 自定义了一个 react-select 下拉组件。当我尝试使用 React.HTMLAttributes<HTMLSelectElement | 扩展界面时 HTML输入元素>。 它显示“没有重载匹配此调用”。 我尝试扩展不同的属性来获取默认值,如 id、label、名称、占位符等。如何获取道具中的默认属性? 有没有人遇到过类似的问题?

示例代码:

import * as React from "react";

import ReactSelect from 'react-select';

export interface SelectProps extends React.HTMLAttributes<HTMLSelectElement | HTMLInputElement> {
    options: Array<any>;
    isMulti: boolean;
    isDisabled: boolean;

};

const Select: React.FC<SelectProps> = (props: SelectProps) => {

    return (<div>
        <label htmlFor={props.id}>{props.label}</label>
        <div>
            <ReactSelect
                {...props}
            />
        </div>
    </div>)
}
export default Select;

使用上述代码后,无法获取 props.id 或 props.name 等。

编辑:

React-Select v5 现在原生支持 TypeScript,因此进行了一些类型更改( 详情)。

这是 v5(react-select/async)的更新示例,类似于 v4 的原始示例:

import ReactSelectAsync, { AsyncProps } from "react-select/async";
import { GroupBase } from "react-select";

interface CustomSelectAsyncProps {
  additionalCustomProp: number;
}

function SelectAsync<
  OptionType,
  IsMulti extends boolean = false,
  GroupType extends GroupBase<OptionType> = GroupBase<OptionType>
>({
  additionalCustomProp,
  ...props
}: AsyncProps<OptionType, IsMulti, GroupType> & CustomSelectAsyncProps) {
  return <ReactSelectAsync {...props} />;
}

export default SelectAsync;

代码沙盒

原答案:

这记录在官方react-select 文档中。

引用:

包装 Select 组件 Select 组件通常包装在另一个在整个应用程序中使用的组件中,并且包装器应该与原始 Select 一样灵活选择)。 为了提供这种灵活性,包装组件应该重新声明 generics 并将它们转发到底层 Select。 以下是如何执行此操作的示例:

function CustomSelect<
  Option,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>(props: Props<Option, IsMulti, Group>) {
  return (
    <Select {...props} theme={(theme) => ({ ...theme, borderRadius: 0 })} />
  );
}

它还解释了如何使用额外的自定义道具来扩展道具:

您可以使用模块扩充将自定义道具添加到 Select 道具类型:

declare module 'react-select/dist/declarations/src/Select' {
  export interface Props<
    Option,
    IsMulti extends boolean,
    Group extends GroupBase<Option>
  > {
    myCustomProp: string;
  }
}

但我个人更喜欢使用带有自定义界面的&字符添加自定义界面来添加自定义道具(例如ReactSelectAsync ,请参阅... & CustomSelectAsyncProps ):

interface CustomSelectAsyncProps {
  additionalCustomProp: number;
}

function SelectAsync<
  OptionType extends OptionTypeBase,
  IsMulti extends boolean = false,
  GroupType extends GroupTypeBase<OptionType> = GroupTypeBase<OptionType>
>({
  additionalCustomProp,
  ...props
}: Props<OptionType, IsMulti, GroupType> & CustomSelectAsyncProps) {
  return (
    <ReactSelectAsync {...props} />
  );
}

你可以这样使用:

import React from 'react'
import { omit } from 'lodash';
import Select, { GroupBase, Props } from 'react-select';

type SelectProps<Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>> = Props<Option, IsMulti, Group> & {
    label?: string;
    id?: string;
}

const SearchableSelect = <
    Option,
    IsMulti extends boolean = false,
    Group extends GroupBase<Option> = GroupBase<Option>
>(props: SelectProps<Option, IsMulti, Group>) => {
    const id = props.id || Math.random().toString()
    const reactSelectProps = omit(props, ['label', 'className'])

    return (
        <div>
            {props.label && (
                <label htmlFor={id} className="block text-sm font-medium text-gray-700">
                    {props.label}
                </label>
            )}
            <Select
                {...reactSelectProps}
                theme={(theme) => ({
                    ...theme,
                    colors: {
                        ...theme.colors,
                        primary: "var(--primary-500)",
                    },
                })}
            />
        </div>
    );
}


export default SearchableSelect

您可以直接从react-select package 中导入Props类型。 您可能想要扩展它以要求同时定义labelid

import React from "react";
import ReactSelect, { Props } from "react-select";

type SelectProps = Props & {
  id: string;
  label: string;
};

const Select: React.FC<SelectProps> = (props) => {
  return (
    <div>
      <label htmlFor={props.id}>{props.label}</label>
      <div>
        <ReactSelect {...props} />
      </div>
    </div>
  );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM