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

如何实现函数双参数类型映射并保证paramMapType的类型安全?

问题描述

我定义了如下枚举:

export enum testEnum {
  key1 = "val1",
  key2 = "val2"
}

有一个函数,第一个参数为testEnum类型,第二个参数的类型由第一个参数传入的枚举值决定,实现如下:

function testFunc<T extends `${testEnum}`>(
    param1: T,
    param2: paramMapType[T],
): Promise<void> { /* ... */ }

同时定义了用于类型映射的类型:

type paramMapType = {
  val1: string;
  val2: boolean
};

现在的问题是paramMapType缺乏类型安全,无法确保其键必须是testEnum的枚举值。我尝试以下写法:

type paramMapType = {
  [key in `${testEnum}`]: any
  val1: string;
  val2: boolean
};

但报错:A mapped type may not declare properties or methods.。用条件类型又太冗长且无法保证类型安全,请问该如何实现?

解决方案

方案一:映射类型+条件类型直接定义

直接通过映射类型遍历testEnum的所有枚举值,搭配条件类型为每个值指定对应参数类型,能严格保证键与枚举值一一对应,不会遗漏或多余:

export enum testEnum {
  key1 = "val1",
  key2 = "val2"
}

type paramMapType = {
  [K in `${testEnum}`]: 
    K extends testEnum.key1 ? string : 
    K extends testEnum.key2 ? boolean : 
    never;
};

function testFunc<T extends `${testEnum}`>(
  param1: T,
  param2: paramMapType[T],
): Promise<void> {
  // 函数实现
  return Promise.resolve();
}

方案二:用satisfies关键字约束(TypeScript 4.9+)

如果希望先手动定义具体的类型映射,再约束其键必须匹配枚举值,可以使用satisfies运算符(TS 4.9及以上版本支持),既保留具体类型信息,又保证类型安全:

export enum testEnum {
  key1 = "val1",
  key2 = "val2"
}

// 定义约束:键必须是testEnum的枚举值
type RequiredParamMap = Record<`${testEnum}`, unknown>;

// 手动定义映射,用satisfies确保符合约束
const paramMapDef = {
  val1: "" as string,
  val2: false as boolean
} satisfies RequiredParamMap;

// 从约束后的对象提取类型
type paramMapType = typeof paramMapDef;

function testFunc<T extends `${testEnum}`>(
  param1: T,
  param2: paramMapType[T],
): Promise<void> {
  return Promise.resolve();
}

原写法报错原因

你之前尝试的混合写法之所以报错,是因为映射类型是批量生成属性的语法,不能与手动声明的属性共存,TypeScript不允许这种混合定义方式。

内容的提问来源于stack exchange,提问作者Tyrion Vu Van Phong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:40:23