使用 TS 泛型来定义通用参数
有些时候会遇到有些业务页面结构是通用的,只是传入页面组件的参数略有不同,这样我们可以使用 TS 的泛型来定义通用参数。具体的实例如下:
type GenericPropsData<T> = {
items: T[];
onClick: (value: T) => void;
};
const GenericProps: React.FC<GenericPropsData<number | string>> = ({
items,
onClick,
}) => {
return (
<div>
<h2>TS 泛型定义参数</h2>
{
items.map((item) => {
return (
<div key={
item} onClick={
() => onClick(item)}>
{
item}
</div>
);
})}
</div>
);
};
export default GenericProps;
上述例子中,只是简单列举了泛型为数字或者字符串,泛型还可以定位为其他对象。
使用 TS 限定传入的参数
有些业务场景要求根据在一定条件下传入对应参数,组件中的其他参数为不能传递的情况,或者出现类型的情况时,我们可以考虑使用 TS 的never
和联合类型
来声明定义参数的组件。具体实例如下:
type RandomNumberType = {
value: number;
};
type PositiveNumber = RandomNumberType & {
isPositive: boolean;
isNegative?: never;
isZero?: never;
};
type NegativeNumber = RandomNumberType & {
isNegative: boolean;
isPositive?: never;
isZero?: never;
};
type Zero = RandomNumberType & {
isZero: boolean;
isPositive?: never;
isNegative?: never;
};
type RandomNumberProps = PositiveNumber | NegativeNumber | Zero;
const RestrictionProps: React.FC<RandomNumberProps> = ({
value,
isPositive,
isNegative,
isZero,
}) => {
return (
<div>
{
value} {
isPositive && "整数"} {
isNegative && "负数"} {
isZero && "0"}
</div>
);
};
export default RestrictionProps;
使用 TS 的 Exclude 去除某些联合类型
我们可以使用 TS 中的 Exclude
来去除某些联合类型的参数,例如下面实例:
type HorizontalPosition = "left" | "center" | "right";
type VerticalPosition = "top" | "center" | "bottom";
/**
* 组件传入的参数可以有如下这些
* "left-center" | "left-top" | "left-bottom" | "center" | "center-top" |
* "center-bottom" | "right-center" | "right-top" | "right-bottom"
*
* 我们通过Exclude抛掉了center-center的值
*/
type ToastProps = {
position:
| Exclude<`${
HorizontalPosition}-${
VerticalPosition}`, "center-center">
| "center";
};
const ExcludeProps: React.FC<ToastProps> = ({
position }) => {
return <div>Toast Notification Position - {
position}</div>;
};
export default ExcludeProps;
使用 TS 实现多态组件
type TextOwnProps<E extends React.ElementType> = {
size?: "sm" | "md" | "lg";
color?: "primary" | "secondary";
children: React.ReactNode;
as?: E;
};
type TextProps<E extends React.ElementType> = TextOwnProps<E> &
Omit<React.ComponentProps<E>, keyof TextOwnProps<E>>;
const PolymorphismProps: React.FC<TextProps<React.ElementType>> = ({
size,
color,
children,
as,
}) => {
const Component = as || "div";
return (
<Component className={
`class-with-${
size}-${
color}`}>{
children}</Component>
);
};
export default PolymorphismProps;