我试图 for each 枚举设置一个类型值,但我不太了解将单个枚举元素映射到类型/接口的语法.

更改某些参数的值需要特定的请求正文,而有些则不需要.ParameterOne和ParameterTwo需要,ParameterTwo不需要.

enum Parameter {
  ParameterOne = 'ParameterOne',
  ParameterTwo = 'ParameterTwo',
  ParameterThree = 'ParameterThree',
}


interface UpdateParameterOneRequestBody {
  name: string;
  age: number;
}

interface UpdateParameterTwoRequestBody {
  id: string;
  timestamp: number;
  price: number;
}

最终主体将始终包括以下界面,以及可选的上述特定主体.

export interface UpdateParameterRequestBody<T extends Parameter> {
  parameter: T;
  value: boolean;
}

因此,它可能会导致UpdateParameterTwoRequestBody & UpdateParameterRequestBody等,但始终包含基础UpdateParameterRequestBody.

我曾try 创建一个类型,然后使用它扩展基础,但似乎我总是需要包含所有参数,它才能工作,我不想这样做.

type ParameterToRequest = {
  [Parameter.ParameterOne]: UpdateParameterOneRequestBody,
  [Parameter.ParameterTwo]: UpdateParameterTwoRequestBody,
};

type ParameterToRequestBody<T extends Parameter> = 
  UpdateParameterRequestBody<T> & T extends Parameter
    ? ParameterToRequestBodyTypes[T]
    : never;

TS2536:类型"T"不能用于索引类型"ParameterToRequestBodyTypes".

Here's a TypeScript Playground

推荐答案

你可以用keyof来解决这个问题,注意你离你所拥有的并不遥远:

type P<T extends Parameter> =
  T extends keyof ParameterToRequestBodyTypes
    ? UpdateParameterRequestBody<T> & ParameterToRequestBodyTypes[T]
    : UpdateParameterRequestBody<T>;

type A = P<'foobar'> // compile-time type error
type B = P<Parameter.ParameterOne> // uses UpdateParameterOneRequestBody 
type C = P<Parameter.ParameterTwo> // uses UpdateParameterTwoRequestBody
type D = P<Parameter.ParameterThree> // only UpdateParameterRequestBody

Playground

Typescript相关问答推荐

Angular 垫页分类和垫排序不起作用

如何在ts中使用函数重载推断参数类型

找不到带名称的管道''

我们过go 不能从TypeScript中的联合中同时访问所有属性?

泛型和数组:为什么我最终使用了`泛型T []`而不是`泛型T []`?<><>

HttpClient中的文本响应类型选项使用什么编码?''

使用Redux Saga操作通道对操作进行排序不起作用

推断从其他类型派生的类型

在保留类型的同时进行深层键名转换

(TypeScript)TypeError:无法读取未定义的属性(正在读取映射)"

如何将对象数组中的键映射到另一种对象类型的键?

与toast.error一起react 中的Async TUNK错误消息

如何将spread operator与typescripts实用程序类型`参数`一起使用

S,为什么我的T扩展未定义的条件在属性的上下文中不起作用?

VITEST警告:当前的测试运行器不支持After Each/teardown挂钩

可以将JS文件放在tsconfig';s includes/files属性?或者,我如何让tsc判断TS项目中的JS文件?

在Vite中将SVG导入为ReactComponent-不明确的间接导出:ReactComponent

什么';是并类型A|B的点,其中B是A的子类?

Next 13 + React 18 createContext 类型的构建问题

我应该使用服务方法(依赖于可观察的)在组件中进行计算吗?