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

TypeScript:实现对象类型到联合类型的类型安全数据转换

类型安全实现键值对象到对应联合对象的转换

你遇到的问题是TypeScript无法自动关联输入键和对应值的映射关系,导致返回类型变成了name与daysAsWWEChamp各自联合类型的任意组合,而非严格匹配TargetType的成员。以下是几种类型安全的解决方式:

方法1:泛型函数+精确类型提取

通过泛型捕获传入的具体键字面量类型,让TypeScript追踪单个键对应的具体值,而非整个联合类型,同时用Extract精准匹配TargetType的对应成员:

const nameToDaysAsWWEChamp = {
  "Stone Cold Steve Austin": 529,
  "The Rock": 378,
  "Hulk Hogan": 2188,
  "Ric Flair": 118,
} as const;

type TargetType =
  | { name: "Stone Cold Steve Austin"; daysAsWWEChamp: 529 }
  | { name: "The Rock"; daysAsWWEChamp: 378 }
  | { name: "Hulk Hogan"; daysAsWWEChamp: 2188 }
  | { name: "Ric Flair"; daysAsWWEChamp: 118 };

function f<K extends keyof typeof nameToDaysAsWWEChamp>(name: K): Extract<TargetType, { name: K }> {
  return { 
    name, 
    daysAsWWEChamp: nameToDaysAsWWEChamp[name] 
  } as Extract<TargetType, { name: K }>;
}

// 调用示例:返回类型严格匹配TargetType中对应的成员
const austinData = f("Stone Cold Steve Austin"); // 类型为{ name: "Stone Cold Steve Austin"; daysAsWWEChamp: 529 }

方法2:简化版泛型函数(自动推导目标类型)

如果不需要显式定义TargetType,可以直接让泛型函数返回精确的键值对类型,完全省略手动类型定义:

const nameToDaysAsWWEChamp = {
  "Stone Cold Steve Austin": 529,
  "The Rock": 378,
  "Hulk Hogan": 2188,
  "Ric Flair": 118,
} as const;

function f<K extends keyof typeof nameToDaysAsWWEChamp>(name: K) {
  return { 
    name, 
    daysAsWWEChamp: nameToDaysAsWWEChamp[name] 
  };
}

// 调用f("Ric Flair")返回的类型为{ name: "Ric Flair"; daysAsWWEChamp: 118 }

方法3:类型断言快速适配(适合简单场景)

如果能保证逻辑完全正确,只是需要快速通过类型校验,可以直接用类型断言指定返回类型为TargetType:

function f(name: keyof typeof nameToDaysAsWWEChamp): TargetType {
  return { 
    name, 
    daysAsWWEChamp: nameToDaysAsWWEChamp[name] 
  } as TargetType;
}

原函数报错原因

当参数是联合类型时,TypeScript会将返回值的name和daysAsWWEChamp分别推断为各自的联合类型,无法保证两者的一一对应关系(比如可能出现name: "The Rock"但daysAsWWEChamp: 529的非法组合),因此TypeScript拒绝将其赋值给严格的TargetType联合类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:05:34