gpt4 book ai didi

reactjs - Typescript 与交集的可区分联合

转载 作者:行者123 更新时间:2023-12-03 08:03:51 26 4
gpt4 key购买 nike

Example sandbox

我有一个类型

type TFormFieldFileProps = {
componentProps: TFileUploaderProps;
select?: never;
checkbox?: never;
file: true;
};

type TFormFieldSelectProps = {
componentProps: TCustomSelectProps;
select: true;
checkbox?: never;
file?: never;
};

type TFormFieldCheckboxProps = {
componentProps: TCustomCheckboxProps;
select?: never;
checkbox: true;
file?: never;
};

type TFormFieldInputProps = {
componentProps: TCustomInputProps;
select?: never;
checkbox?: never;
file?: never;
};

export type TFormFieldProps = { boxProps?: BoxProps } & (
| TFormFieldCheckboxProps
| TFormFieldInputProps
| TFormFieldSelectProps
| TFormFieldFileProps
);

我想删除 componentProps 属性,并将每种类型设置为 componentProps 属性类型与其他 select checkbox file 类型的交集.

type TFormFieldFileProps = TFileUploaderProps & {
select?: never;
checkbox?: never;
file: true;
};

type TFormFieldSelectProps = TCustomSelectProps & {
select: true;
checkbox?: never;
file?: never;
};

type TFormFieldCheckboxProps = TCustomCheckboxProps & {
select?: never;
checkbox: true;
file?: never;
};

type TFormFieldInputProps = TCustomInputProps & {
select?: never;
checkbox?: never;
file?: never;
};

export type TFormFieldProps = { boxProps?: BoxProps } & (
| TFormFieldCheckboxProps
| TFormFieldInputProps
| TFormFieldSelectProps
| TFormFieldFileProps
);

但是这不起作用。

const FormField = (props: TFormFieldProps) => {
const { select, checkbox, file, boxProps, ...rest } = props;

return (
<Box
{...boxProps}
sx={{ '& > *': { width: 1 } }}
>
{select ? (
// error: missing some property from TFormFieldCheckboxProps
<CustomSelect {...rest} />
) : checkbox ? (
// error: missing some property from TFormFieldInputProps
<CustomCheckbox {...rest} />
) : file ? (
// error: missing some property from ...
<FileUploader {...rest} />
) : (
// error: missing some property from ...
<CustomInput {...rest} />
)}
</Box>
);
};

我明白为什么它不起作用,但我不明白如何解决这个问题,而不必指定每种类型的每个属性...

我可以在不编写所有可区分联合类型中所有类型的所有 Prop 的情况下使其工作吗?如果是这样,怎么办?

最佳答案

为了清楚起见,这里的问题是,虽然 TypeScript 4.6 及更高版本支持 control flow analysis on destructured discriminated unions ,这不适用于 rest properties (从 TypeScript 4.7 开始)。

所以,这有效:

interface Foo { type: "foo"; rest: { x: string } }
interface Bar { type: "bar"; rest: { y: number } }

const process = ({ type, rest }: Foo | Bar) =>
type === "foo" ? rest.x : rest.y; // okay

但这失败了:

interface Foo { type: "foo"; x: string }
interface Bar { type: "bar"; y: number }

const process = ({ type, ...rest }: Foo | Bar) =>
type === "foo" ? rest.x : rest.y; // errors
// -------------------> ~ -----> ~
// Property does not exist on {x: string} | {y: number}

最近有一个公开请求:microsoft/TypeScript#46680支持这一点,但尚未实现。您可能想给这个问题一个👍和/或提及您的用例(以及为什么它引人注目),但我不知道它是否会产生任何效果。

Playground link to code

关于reactjs - Typescript 与交集的可区分联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73087653/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com