从 Union 类型构建复杂类型

Build a complex type from Union type

我正在尝试从平面联合类型构建具有两层的类型

这是我的代码:

type TextVariants =
  | {
      size: 'tiny'
      // available variants for this size
      variants:
        | 'regularNormal'
    }
  | {
      size: 'super'
      // available variants for this size
      variants:
        | 'regularNone'
    }

type TextSizesProps = {
  [k in TextVariants['size']]: {
    css: Object
    variants: {
      [v in TextVariants['variants']]: Object
    }
  }
}

const textSizes: TextSizesProps = {
  tiny: {
    css: {
      fontSize: '$tiny',
    },
    variants: {
      // Here TS is complaining about missing "regularNone" but shouldn't
      regularNormal: {
        lineHeight: '$normal',
        fontWeight: '$regular',
      },
    },
  },
  super: {
    css: {
      fontSize: '$super',
    },
    variants: {
      // same
      regularNone: {
        lineHeight: '$none',
        fontWeight: '$regular',
      },
      },
    },
  },
}

我对每种文字大小都有不同的名称,我需要它被识别

这是 typescript playground

的 link

感谢任何帮助

你应该这样尝试:

type TextSizesProps = {
  [V in TextVariants as V["size"]]: {
    css: Object
    variants: {
      [v in V["variants"]]: Object
    }
  }
}

TextVariants['size'] 中创建一个映射类型,然后再从 TextVariants['variants'] 中创建一个映射类型将导致一个允许所有大小的所有变体的联合。

但是如果您映射不同的 TextVariants,您可以将每个变体存储在 V 中。 V 现在表示特定变体,可用于访问变体 variantsize 属性。

Playground

如果您愿意,可以将 TextVariants 类型的定义更改为对象类型,这样您就可以迭代 TextSizesProps 类型中的键。

例如:

type TextVariants = {
  tiny:
    | "regularNormal";
  super:
    | "regularNone";
}

type TextSizesProps = {
  [K in keyof TextVariants]: {
    css: Object;
    variants: {
      [V in TextVariants[K]]: Object;
    }
  }
}

或允许将来添加更多字段:

type TextVariants = {
  tiny: {
    variants: 
      | "regularNormal";
  };
  super: {
    variants:
      | "regularNone";
  };
}

type TextSizesProps = {
  [K in keyof TextVariants]: {
    css: Object;
    variants: {
      [V in TextVariants[K]["variants"]]: Object;
    }
  }
}