TypeScript:如何缩小/编写复杂条件类型的保护



给定以下MultiselectValue条件类型,如何根据multiple的值或通过Comp内部的保护将其解析为LabeledValue<T>Array<LabeledValue<T>>

export interface LabeledValue<T = unknown> {
label: string;
value: T;
}
export type MultiselectValue<T, Multiple> = Multiple extends (undefined | false)
? LabeledValue<T>
: Array<LabeledValue<T>>;
export type MultiselectProps<T, Multiple extends boolean | undefined> = {
multiple: Multiple;
value: MultiselectValue<T, Multiple>;
}
Comp({
multiple: true,
value: [{ // tsc complains if not an array (as expected) because 'multiple' is 'true'
label: 'Option 1',
value: 5
}]
});
function Comp<T, Multiple extends boolean | undefined = undefined>(props: MultiselectProps<T, Multiple>) {
const { multiple, value } = props;
if (multiple) {
// value is an arrray here
} else {
// value is a string here
}
}

TS游乐场链接

编辑:接受答案的非通用版本

最简单的方法是实际更改MultiselectProps:的定义

type MultiselectProps<T, Multiple extends boolean | undefined> = Multiple extends (undefined | false) ? {
multiple: Multiple;
value: LabeledValue<T>;
} : {
multiple: Multiple;
value: Array<LabeledValue<T>>;
};

现在,在函数体中,props是一个有区别的并集(未解析类型(,这意味着您可以像已经做过的那样缩小它的范围。

游乐场

最新更新