是否可以在打字稿中对联合类型进行条件解构?

问题描述 投票:0回答:3

我有一个带有打字稿的 React 应用程序(尽管问题并不是真正关于 React)。

在功能组件中(我希望其使用者能够传递 OR 样式或类,但不能同时传递两者),我使用以下 props 类型:

type AnimationContainerProps = { hidingTimeoutMs: number } & (
    | {
        displayingClass: string;
        hidingClass: string;
      }
    | {
        displayingInlineStyle: string;
        hidingInlineStyle: string;
      }
  );

我想用一条指令来解构它,例如:

const { hidingTimeoutMs, displayingClass, hidingClass, displayingInlineStyle, hidingInlineStyle } = props

在 javascript 中,这不会有问题,我会在不存在的 props 中收到

undefined
。但在 Typescript 中,我不能这样做,因为我会得到一个
Property 'XXX' does not exist on type 'AnimationContainerProps'.ts(2339)

我想避免一一归因。你们有办法解构它吗?

typescript destructuring
3个回答
1
投票

这是您可以做到的一种方法:

const { hidingTimeoutMs, displayingClass, hidingClass, displayingInlineStyle, hidingInlineStyle } = {
    displayingClass: undefined,
    hidingClass: undefined,
    displayingInlineStyle: undefined,
    hidingInlineStyle: undefined,
    ...props
};

对于缺少的属性,您可以使用

undefined
或任何其他方便的值或对象。


0
投票

TypeScript 强制执行类型一致性,因此您有两种选择来保留类型强制。

选项 1 - 叠加:

type AnimationContainerProps = { hidingTimeoutMs: number } & { option: (
  | {
    displayingClass: string;
    hidingClass: string;
    }
  | {
    displayingInlineStyle: string;
    hidingInlineStyle: string;
    }
) };

let props = {} as AnimationContainerProps;
const { hidingTimeoutMs, option } = props;

选项 2 - 分解:

type AnimationContainerProps = {
  hidingTimeoutMs: number;
  displayingClass: string | undefined;
  hidingClass: string | undefined;
  displayingInlineStyle: string | undefined;
  hidingInlineStyle: string | undefined;
};

let props = {} as AnimationContainerProps;

const { hidingTimeoutMs, displayingClass, hidingClass, displayingInlineStyle, hidingInlineStyle } = props;

0
投票

您可以使用

typeGuard
函数来决定从 props 中解构哪些内容(
inline
class

// Type guard function
const hasInlineStyles = (
  props: AnimationContainerProps
): props is {
  displayingInlineStyle: string;
  hidingInlineStyle: string;
  hidingTimeoutMs: number;
} => 'displayingInlineStyle' in props;

// Example usage in your component
const Component = (props: AnimationContainerProps) => {
  const { hidingTimeoutMs } = props;

  if (hasInlineStyles(props)) {
    const { displayingInlineStyle, hidingInlineStyle } = props;
    // Use displayingInlineStyle and hidingInlineStyle
  } else {
    const { displayingClass, hidingClass } = props;
    // Use displayingClass and hidingClass
  }

  // Rest of your component logic
};

© www.soinside.com 2019 - 2024. All rights reserved.