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

TypeScript:传递对象字面量作为参数时如何避免类型拓宽?

在最新TypeScript版本中,能否避免对象字面量参数的类型拓宽且无需使用as const?

问题说明

希望在最新TypeScript版本中,实现将对象字面量作为函数参数传递时,自动保留属性值的字面量类型(避免被拓宽为string),同时调用函数时不需要额外添加as const断言。具体要求是该实现需支持所有扩展Record<string, string>的对象字面量。

当前实现代码

function func<T>(value: T): T { 
    return value;
};

let test = func({ key: 'value' })
// 类型推断结果:{ key: string;}

期望效果

// 改写func的声明后

let test = func({ key: 'value' })
// 类型推断结果:{ key: "value"; }

现有可行但不符合需求的方式

以下两种写法能达到期望的类型推断效果,但需要修改函数调用方式,不符合需求:

function func<T>(value: T): T {
    return value
};

let test = func({ key: 'value' as const })
// 类型推断为 { key: "value"; }

let test = func({ key: 'value' } as const )
// 类型推断为 { readonly key: "value"; }

解决方案

方案1:兼容旧版本的映射类型实现

通过自定义映射类型,将对象的字符串属性值强制转为字面量类型,同时约束输入类型为Record<string, string>的子类型:

type Literalize<T extends Record<string, string>> = {
  [K in keyof T]: T[K] extends string ? `${T[K]}` : T[K];
};

function func<T extends Record<string, string>>(value: Literalize<T>): Literalize<T> {
  return value;
}

let test = func({ key: 'value' });
// 类型推断结果:{ key: "value"; }

方案2:TypeScript 5.0+的const泛型参数(推荐)

TypeScript 5.0及以上版本支持const修饰泛型参数,直接让TypeScript对传入的对象字面量进行窄化推断,保留原始字面量类型:

function func<const T extends Record<string, string>>(value: T): T {
  return value;
}

let test = func({ key: 'value' });
// 类型推断结果:{ key: "value"; }

该方案无需额外定义类型,代码更简洁,但要求TypeScript版本≥5.0。

内容的提问来源于Stack Exchange,提问作者dsalex1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:06:24