簡體   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