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

如何基于键值推断TypeScript类型?实现getAllRaces精准推导

问题:让getAllRaces()类型推断为() => Race[]

我尝试让getAllRaces()的类型推断为() => Race[],但当前推断结果是() => Race[] | Horse[],以下是我的代码和失败尝试:

type CollectionMap = {
    races: Race[]
    horses: Horse[]
}

type Race = {
    date: Date
}

type Horse = {
    name: string
}

type UnionizeKeys<T> = {
    [k in keyof T]: k
}[keyof T]

type CollectionName = UnionizeKeys<CollectionMap> // "races" | "horses"

// 失败的尝试
const getAll1 = (name: CollectionName) =>  [] as CollectionMap[name];
// 💥 错误:Type 'name' cannot be used as an index type.(2538)

const getAll2 = (name: CollectionName) =>  [] as CollectionMap[typeof name as const];
// 💥 错误:A 'const' assertions can only be applied to references to enum members,
//    or string, number, boolean, array, or object literals.(1355)

const getAll = (name: CollectionName) =>  [] as CollectionMap[typeof name];

const getAllRaces = () => getAll('races')
// ❌ 当前推断:const getAllRaces: () => Race[] | Horse[]
// ✅ 期望结果:const getAllRaces: () => Race[]

解决方法

给getAll添加泛型约束,让TypeScript根据传入的具体集合名称字面量类型,推断出对应的返回类型:

const getAll = <T extends CollectionName>(name: T) => [] as CollectionMap[T];

const getAllRaces = () => getAll('races')
// ✅ 现在推断类型:const getAllRaces: () => Race[]

原理说明

原来的getAll函数参数是CollectionName联合类型,返回值被推断为CollectionMap[CollectionName](即Race[] | Horse[]),所以调用后始终返回联合类型。

通过泛型T extends CollectionName,TypeScript会捕获传入的具体字面量类型(比如调用getAll('races')时,T被推断为"races"),从而返回精确的CollectionMap[T]类型(即Race[])。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:37:43