React 泛型组件

背景

场景:封装一个 antd 的 Radio 组件时,需要从父组件获取到 value 的类型。其 props 接口定义如下

interface CustomRadioProps<ValueType> {
  options: Option<ValueType>[];
  value: ValueType;
  onChange: (value: ValueType) => void;
}

使用时这里假设传进去的是个 number 类型

<CustomRadio<number>
  onChange={handleTypeChange}
  options={[
    {
      label: '1',
      value: 1,
    },
    {
      label: '1',
      value: 2,
    },
  ]}
  value={1}
/>

那么这个 CustomRadioProps 称为泛型组件。

那么如何定义一个泛型组件?

类组件

class CustomRadio<T> extends React.Component<Props<T>> { 
	// ...
}

函数组件

对于用 function 声明的函数式组件实际上于泛型函数是一样的写法:

function CustomRadio<T>(props: IProps<T>) {
	// ...
}

然而对于用箭头函数不可以这么写:

const CustomRadio: React.FunctionComponent<IProps<T>> = props => { /*...*/ } 

箭头函数组件正确的写法:

const IconRadioGroup = <T extends any>(props: IProps<T>) => {
	// ...
}

这里 T 必须要使用 extends, 用 T extends any 来表明接收任意类型,如果只能 number 或者 string类型,则改成 T extends number|string 即可。