首页 文章

使用$ Keys字符串文字键入流中的对象作为键但具有不同的值

提问于
浏览
0

我认为这个问题最好用一个例子说明,假设我们有一个以下形式的对象:

type colorsType = $Keys<typeof colors>;

type ThemeColorTypes =
    {|
          +extraLight: string,
          +light: string,
          +normal: string,
          +dark: string,
          +extraDark: string
      |}

type theme = {
    +colors: { [colorsType]: ThemeColorTypes },
}

在这种情况下,颜色也是一个对象文字,颜色名称(不包括白色)作为键,ThemeColorTypes的属性作为值 .

这很好用但是对于白色我想添加更具体的类型 . 颜色中的“白色”键应始终为值“#ffffff”(因为没有更亮/更深的白色版本) .

我的第一次尝试是:

type theme = {
        +colors: { 
          [colorsType]: ThemeColorTypes, 
          white: "#ffffff" 
        },
    }

不幸的是,这不起作用 . 这导致了很多:

[Flow] Cannot get `theme.colors.primary.normal` because property `normal` is missing in `String` [1].

错误 .

当然,我可以更改ThemeColorTypes的定义,以便字符串也是一个可能的值,但是每次我想使用normal / dark / extraDark / etc时我都要检查颜色是字符串还是对象 .

我想流程知道,当我访问“白色”时,它总是一个字符串,但对于其他颜色,它是一个特定形状的对象 .

我已经google了一下,似乎他们对如何在Flow中实现它们有一些限制,但我找不到如何实现这一点的非常好的答案 .

所以更一般的问题是,如何使用 $Keys 和具有不同定义的文字键的组合在流中键入对象?

1 回答

  • 1

    最直接的解决方案是使用optional object properties

    type theme = {
      +colors: {
           [colorsType]: ThemeColorTypes,
           white?: '#fff'
       },
    }
    

    如果错过 white 就没关系,但如果 white 存在则应为 #fff .

    你也可以试试spread operators

    type WhiteThemeColorType = { white: '#fff' };
    
    type theme = {
      +colors: { [colorsType]: ThemeColorTypes, ...WhiteThemeColorType },
    }
    

    或者内联:

    type theme = {
      +colors: {
         [colorsType]: ThemeColorTypes,
         ...{ white: '#fff' }
       }
    }
    

    Flow playground . 希望它能为您解决如何解决这个问题提供一些指导 .

相关问题