You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Enum从Interface推导类型?TypeScript泛型报错解决

TypeScript 自动推导资源类型的优雅实现

问题背景

我定义了资源类型枚举ResourceType:

enum ResourceType {
  Blog = "blogs",
  BlogAuthor = "blog_authors",
  [...]
}

以及对应资源类型的定义接口ResourceDefinitions:

interface ResourceDefinitions {
  [ResourceType.Blog]: BlogResource;
  [ResourceType.BlogAuthor]: BlogAuthorResource;
  [...]
}

目标是调用const resource = useResource(ResourceType.Blog, id);时,resource能自动推导为BlogResource类型。最初尝试的useResource定义如下:

const useResource = <P extends ResourceType, T = ResourceDefinitions[P]>(
  type: P,
  id: string
): T => {
  [...]
};

但这段代码触发TypeScript错误:TS2536: Type 'P' cannot be used to index type 'ResourceDefinitions'。

目前有两种可行但不够优雅的方案:

  1. 手动指定泛型类型
const useResource = <T>(
  type: ResourceType,
  id: string
): T => {
  [...]
};

const resource = useResource<BlogResource>(ResourceType.Blog, id);
  1. 手动添加类型断言
const useResource = <P extends keyof ResourceDefinitions, T = ResourceDefinitions[P]>(
  type: P,
  id: string
): T => {
  [...]
};

const resource = useResource(ResourceType.Blog as keyof ResourceDefinitions, id);

优雅解决方案

只需要简化泛型定义,直接让返回类型关联枚举参数与资源定义的映射:

const useResource = <P extends ResourceType>(
  type: P,
  id: string
): ResourceDefinitions[P] => {
  // 内部实现逻辑
};

效果说明

调用useResource(ResourceType.Blog, id)时,TypeScript会自动将泛型P推导为ResourceType.Blog,进而返回ResourceDefinitions[ResourceType.Blog]对应的BlogResource类型,完全满足自动推导需求,且无任何类型错误。

原理

原来的错误是因为TypeScript无法默认确认P extends ResourceType的所有成员都属于ResourceDefinitions的有效键,但我们的ResourceDefinitions的键本身就是ResourceType的枚举值,因此直接将返回类型设为ResourceDefinitions[P],同时保留P extends ResourceType的约束,TypeScript就能正确识别这个映射关系,无需额外的断言或手动指定类型。

内容的提问来源于stack exchange,提问作者Arthur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 08:47:14