我對 Typescript 很陌生,我正在嘗試基于函式引數值進行條件擴展。背景關系是為物件選擇定義一個小部件,它可以是選擇、單選串列(單選組)或復選框串列(復選框組)。這每一個不同的小部件接受不同的道具,名稱:SelectProps,RadioGroupProps和CheckboxGroupProps。小部件選擇基于兩個引數:(expand意味著我們想要一個復選框或單選串列)和multiple(意味著我們想要選擇或不選擇多個元素)。
function SelectionWidget(props: SelectionWidgetProps) {}
在這里,我想要:
如果props匹配{expand: true, multiple: false}則SelectionWidgetProps必須擴展RadioGroupProps。
如果props匹配{expand: true, multiple: true}則SelectionWidgetProps必須擴展CheckboxGroupProps。
否則,SelectionWidgetProps必須擴展SelectProps。
我嘗試了以下方法:
type SelectTypeExtend<T> =
T extends { expand: false } ? SelectProps :
T extends { expand: true; multiple: false } ? RadioGroupProps :
T extends { expand: true; multiple: true; } ? CheckboxGroupProps :
never;
interface SelectTypeProps extends SelectTypeExtends {
multiple?: boolean;
expand?: boolean;
}
但它不像SelectTypeExtends預期的那樣起作用。是否可以使用 Typescript 實作這一目標?謝謝!
uj5u.com熱心網友回復:
您interface只能使用靜態已知型別進行擴展。這意味著不允許您擴展SelectTypeProps,SelectTypeExtends因為它SelectTypeExtends是一個黑匣子。沒有人知道T.
為了管理這種情況,您應該使用type而不是interface:
type SelectProps = {
tag: 'SelectProps'
}
type RadioGroupProps = {
tag: 'RadioGroupProps'
}
type CheckboxGroupProps = {
tag: 'CheckboxGroupProps '
}
type SelectTypeExtend<T> =
T extends { expand: false } ? SelectProps :
T extends { expand: true; multiple: false } ? RadioGroupProps :
T extends { expand: true; multiple: true; } ? CheckboxGroupProps :
never;
type SelectTypeProps<T> = { // <------ type instead of interface
multiple?: boolean;
expand?: boolean;
} & SelectTypeExtend<T>
帶有反應組件的示例:
import React from "react";
import {
Select,
SelectProps,
Checkbox,
CheckboxGroupProps,
Radio,
RadioGroupProps
} from "formik-antd";
export type SelectionComponentProps =
| { expand?: false } & { options: SelectProps }
| { expand: true; multiple?: false } & { options: RadioGroupProps }
| { expand: true; multiple: true } & { options: CheckboxGroupProps };
function SelectionComponent(props: SelectionComponentProps) {
if (props.expand) {
if (props.multiple) {
return <Checkbox.Group {...props.options} />;
} else {
return <Radio.Group {...props.options} />;
}
}
return <Select {...props.options} />;
};
const select: SelectProps = 'unimplemented' as any;
const radio: RadioGroupProps = 'unimplemented' as any;
const checkbox: CheckboxGroupProps = 'unimplemented' as any;
export const TestRadio = () => {
// Accept properties from RadioGroupProps but not from SelectProps or CheckboxGroupProps
return [
<SelectionComponent expand options={radio} />, // ok
<SelectionComponent expand options={select} />, // expected error
<SelectionComponent expand options={checkbox} />, // expected error
]
};
export const TestCheckbox = () => {
// Accept properties from CheckboxProps but not from SelectProps or RadioGroupProps
return [
<SelectionComponent expand multiple options={checkbox} />, // ok
<SelectionComponent expand multiple options={select} />, // expected error
<SelectionComponent expand multiple options={radio} /> // expected error
]
};
export const TestSelect = () => {
// Accept properties from SelectProps but not from RadioGroupProps or CheckboxGroupProps
return [
<SelectionComponent options={select} />, // ok
<SelectionComponent options={radio} />, // expected error
<SelectionComponent options={checkbox} />, // expected error
]
};
操場
我稍微修改了SelectionComponentProps型別。請記住,如果您不提供一些屬性來回應組件,TS 會將其視為undefined而不是false,因此您需要將您的一些false屬性作為partial
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/409675.html
標籤:
上一篇:方法裝飾器應該回傳第一個執行結果Typescript
下一篇:如何附加到編譯時常量
