这里有一个例子.

const a = {
  type: 'file',
  file: 'foo',
}
const b = {
  type: 'emoji',
  emoji: 'bar',
}
const c = {
  type: 'external',
  external: 'baz',
}

第二个属性始终为string.主要问题是使用泛型将值type用作键.

如果同时使用zodTypeScript会更好!

我试过了

type IconType = 'file' | 'emoji' | 'external'

type IconFile<T extends IconType = IconType> = {
  type: T
  [key in T]: string
}

但有一个错误:A mapped type may not declare properties or methods

推荐答案

有两个问题需要解决:

Problem 1: Mapped type with extra properties

您需要使用intersection type:

type IconType = 'file' | 'emoji' | 'external'

type IconFile<U extends IconType & string> = { type: U } & { [P in U]: string }

const x: IconFile<'file'> = {
  type: 'file',
  file: 'string'
}

请注意类型为字符串的IconFile上的额外泛型参数.

Problem 2: Map union type to another union type

我们想要一件IconFile<'file'> | IconFile<'emoji'> | IconFile<'external'>码的

您可以对distributing over the members of the union type使用条件类型

type DistributeToIconFile<U extends IconType & string> = U extends string 
  ? IconFile<U> 
  : never;
  
type IconFileAsUnion = DistributeToIconFile<IconType>
    // ^? 
    // type IconFileAsUnion = IconFile<'file'> | IconFile<'emoji'> | IconFile<'external'>

const a: IconFileAsUnion = {
  type: 'file',
  file: 'myfile'
};

TypeScript: Map union type to another union type

请注意,Simple IconFile<IconType>不会分发unions 成员

const nodDistributedBadApproach: IconFile<IconType> = {
  type: 'file',
  file: 'string1',
  emoji: 'string2',
  external: 'string3'
}

Playground

Typescript相关问答推荐

在Switch陈述中输入保护类

如何获取数组所有可能的索引作为数字联合类型?

调用另一个函数的函数的Typescript类型,参数相同

ReturnType此索引方法与点表示法之间的差异

如何推断类方法未知返回类型并在属性中使用它

如何在第一次加载组件时加载ref数组

类型脚本泛型最初推断然后设置

如何根据另一个属性的布尔值来缩小函数属性的返回类型?

TypeScrip原始字符串没有方法

如何在TypeScrip中正确键入元素和事件目标?

为什么在回调函数的参数中不使用类型保护?

为什么Typescript不能推断类型?

有没有办法取消分发元组的联合?

带投掷的收窄类型

如何定义这样一个TypeScript泛型,遍历路由配置树并累积路径

打字:注解`是字符串`而不是`布尔`?

React中的效果挂钩在依赖项更新后不会重新执行

如何使用 Angular 确定给定值是否与应用程序中特定单选按钮的值匹配?

typeof 运算符和泛型的奇怪行为

从平面配置推断嵌套递归类型