字符串联合的打字稿并发症

Posted

技术标签:

【中文标题】字符串联合的打字稿并发症【英文标题】:Typescript complications with string unions 【发布时间】:2021-06-20 17:11:19 【问题描述】:

我正在尝试创建一个根据 name 属性返回 JSX 的函数。 这是我的代码:

function TabBarIcon(props: 
  name:
    | React.ComponentProps<typeof Ionicons>['name'] // 'key' | 'item' | 2000 more...
    | React.ComponentProps<typeof Feather>['name']; // 2000 different strings...
  color: string;
  type: 'Ionicons' | 'Feather';
) 
  if (props.type === 'Ionicons')
    return <Ionicons size=30 style= marginBottom: -3  ...props />;
  else if (props.type === 'Feather')
    return <Feather size=30 style= marginBottom: -3  ...props />;
  else return <View />;

TypeScript 会引发错误,因为它不能确定 &lt;Ionicons /&gt;&lt;Feather /&gt; 组件是否包含名称。我试图用 props.type 来解决这个问题,但 TypeScript 仍然会引发错误。如何在没有错误的情况下返回正确的组件?谢谢!

【问题讨论】:

能否提供错误信息? 请考虑将此处的代码修改为minimal reproducible example,将其放入像The TypeScript Playground 这样的独立IDE 时,可以清楚地表明您的问题。或者,如果这不可能,请考虑提供一个链接,指向正确配置的 Web IDE 项目,以证明您的问题。这将帮助人们解决问题并提高您获得的答案的质量。大概问题是props 不是discriminated union 的形式。 这是一个链接,但它给出了不同的错误:snack.expo.io/GsNspaqKf。我设备上的错误是“属性‘名称’的类型不兼容。” 看起来 IDE 需要的是 JS 而不是 TS 代码。如果我看不到您所看到的相同问题,那么我很难对它做任何事情。也许您可以解决这个问题,或者尝试将问题减少到没有外部依赖的问题。 【参考方案1】:

看起来Ionicons 有超过 3,000 个名称,而 Feather 有更多的 300 个名称。如果我使用 type="Feather" 和仅存在于 Ionicons 上的名称调用您的组件会怎样?

您的组件是这样键入的,如果name 存在于IoniconsFeather 上,则它是一个有效的道具。但这还不够好。我们需要知道图标存在于所选图标集上

将 props 定义为 union 将使错误消失。

function TabBarIcon(props:  
  color: string;
 & (
  
    name: React.ComponentProps<typeof Ionicons>['name'];
    type: 'Ionicons';
   | 
    name: React.ComponentProps<typeof Feather>['name'];
    type: 'Feather';
)) 
  if (props.type === 'Ionicons')
    return <Ionicons size=30 style= marginBottom: -3  ...props />;
  else if (props.type === 'Feather')
    return <Feather size=30 style= marginBottom: -3  ...props />;
  else return <View />;

【讨论】:

谢谢,这成功了!作为后续,是否可以在不包含 'type' 属性的情况下避免 TS 错误? 您这样做的目标是什么?没有 type 属性你不知道哪个图标集。 我希望有一种方法可以通过检查名称字符串以及它所属的集合来检查要创建的图标(假设这些集合是互斥的) 在您担心类型之前,我会看看这是否可能。

以上是关于字符串联合的打字稿并发症的主要内容,如果未能解决你的问题,请参考以下文章

“联合类型值到字符串的映射”的打字稿类型?

类型为 String 时如何在 DB 中查找项目 |使用打字稿联合类型的字符串 []

无法让嵌套类型保护与打字稿中的联合类型一起使用

打字稿:对象和原语之间的keyof typeof联合总是永远不会

字符串枚举类似于打字稿中的类型[重复]

打字稿:将标记的联合转换为联合类型