【问题标题】:Typescript throws error with spread operatorTypescript 使用扩展运算符引发错误
【发布时间】:2020-01-26 00:47:12
【问题描述】:

我有以下简单的 React 组件:

export interface BadgeProps {
  children: React.ReactNode | string | React.ReactNode[],
  layout: "gray" | "danger" | "success" | "brand",
  size?: "sm" | "base",
}

const Badge: React.FC<BadgeProps> = ({ children }) => {
  return (
    <div data-test="component-badge">{children}</div>
  );
}

当我现在以这种方式调用组件时,它可以正常工作:

<Badge layout="gray">Text</Badge>

但是当我使用扩展运算符传递道具时,我收到以下错误。

const props = { layout: "gray" };
return (
  <Badge {...props}>Text</Badge>
);

类型“字符串”不可分配给类型“灰色”| “危险” | “成功” | “品牌”'

我觉得它应该可以正常工作,但我不知道它为什么会失败。这是对 Typescript 工作原理的误解吗?

【问题讨论】:

  • 试试const props = { layout: "gray" } as const;const props = { layout: "gray" as const };。 TypeScript 必须推断 props 的类型,并且它认为您希望将 layout 属性扩大到 string;也许您想为它分配一些不同的string 属性,例如props.layout = "cheese sticks"。它不知道你需要它保持狭窄。对不起,它正在尽力而为????
  • 您是否尝试使用枚举来代替?没有回答错误背后的主要问题,但可能是将您的道具提供给组件的解决方案。
  • @jcalz 成功了,谢谢
  • @JonathanStellwag 也想过枚举,但我发现在尝试使用组件时导入枚举也有点烦人。你能告诉我使用枚举与我的方法相比有什么优势吗?
  • @MaxTommyMitschke 枚举通常比字符串文字更好。它更容易重构,找到用法。此外,如果您不需要在运行时获取枚举名称,则应使用 const 枚举。常量枚举被完全删除,并且它们的值在运行时被硬编码。见diff

标签: reactjs typescript


【解决方案1】:

这是因为"gray" | "danger" | "success" | "brand" 是一种特定类型,只能是其中一个字符串,但是当您这样分配时:

const props = { layout: "gray" };

Typescript 推断 layout 属性是 string 而不是您的特殊类型,因此会出错。

为了修复这个错误,你需要自己标记类型。

export type LayoutType = "gray" | "danger" | "success" | "brand";

export interface BadgeProps {
  children: React.ReactNode | string | React.ReactNode[],
  layout: LayoutType,
  size?: "sm" | "base",
}

const Badge: React.FC<BadgeProps> = ({ children }) => {
  return (
    <div data-test="component-badge">{children}</div>
  );
}



const props: { layout: LayoutType } = { layout: "gray" };
// ------------------------^ your layout type 
return (
  <Badge {...props}>Text</Badge>
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-07
    • 2021-04-08
    • 2018-05-15
    • 2022-09-23
    • 2017-04-30
    • 2023-03-25
    • 2021-09-02
    • 2023-02-25
    相关资源
    最近更新 更多