扩展React FC通用Typescript组件(Ant Design Select)



我正在尝试扩展ant设计的Select组件。可以使用这样的组件:

<Select<number>>
...
</Select>

现在我想创建一个自定义包装器组件,但通用嵌套对我来说真的很难理解。

const BMSelect: React.FC<SelectProps<???>> = ({children, ...props}) => {
return <Select<???> {...props}>
{children}
</Select>
}

如何使用typescript扩展此select?

Ant设计提供了以下接口/道具:

import * as React from 'react';
import { Option, OptGroup, SelectProps as RcSelectProps } from 'rc-select';
import { OptionProps } from 'rc-select/lib/Option';
import { SizeType } from '../config-provider/SizeContext';
declare type RawValue = string | number;
export { OptionProps };
export declare type OptionType = typeof Option;
export interface LabeledValue {
key?: string;
value: RawValue;
label: React.ReactNode;
}
export declare type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[];
export interface InternalSelectProps<VT> extends Omit<RcSelectProps<VT>, 'mode'> {
suffixIcon?: React.ReactNode;
size?: SizeType;
mode?: 'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
bordered?: boolean;
}
export interface SelectProps<VT> extends Omit<InternalSelectProps<VT>, 'inputIcon' | 'mode' | 'getInputElement' | 'backfill'> {
mode?: 'multiple' | 'tags';
}
export interface RefSelectProps {
focus: () => void;
blur: () => void;
}
declare const SelectRef: <VT extends SelectValue = SelectValue>(props: SelectProps<VT> & {
ref?: ((instance: RefSelectProps | null) => void) | React.RefObject<RefSelectProps> | null | undefined;
}) => React.ReactElement;
declare type InternalSelectType = typeof SelectRef;
interface SelectInterface extends InternalSelectType {
SECRET_COMBOBOX_MODE_DO_NOT_USE: string;
Option: typeof Option;
OptGroup: typeof OptGroup;
}
declare const Select: SelectInterface;
export default Select;

您的组件还需要获得一个通用参数,该参数可以传递给它扩展的组件。

我不知道有什么方法可以从函数外部引用函数内部的泛型参数,但您当然可以使用函数定义并显式键入props,而不是使用React.FC

function BMSelect<T>({ children, ...props }: SelectProps<T>) {
return (
<Select<T> {...props}>
{children}
</Select>
);
}

如果您查看ant design-select组件的源代码,您会发现它所使用的泛型参数扩展了SelectValue

const InternalSelect = <VT extends SelectValue = SelectValue>(

您需要对T应用相同的约束才能正确扩展其组件。

function BMSelect<T extends SelectValue>({ children, ...props }: SelectProps<T>) {
return (
<Select<T> {...props}>
{children}
</Select>
);
}

接受的答案正在按预期工作。然而,我想在这里添加基于箭头函数的方法:

const BMSelect = <T extends SelectValue = SelectValue>({ children, ...props }: SelectProps<T>) => {
return (
<Select<T> {...props}>
{children}
</Select>
);
}

最新更新