首页 > 解决方案 > 扩展 React-FC Generic Typescript-Component (Ant-Design Select)

问题描述

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

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

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

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

如何使用打字稿扩展此选择?

Ant-design 提供以下接口/道具:

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;

标签: reactjstypesantd

解决方案


你的组件还需要接受一个通用参数,它可以传递给它扩展的组件。

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

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

如果您查看ant-design select 组件的源代码,您会看到它采用的通用参数 extends SelectValue

const InternalSelect = <VT extends SelectValue = SelectValue>(

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

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

推荐阅读