[英]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
類型。 您可能想要擴展它以要求同時定義label
和id
。
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.