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

如何让TypeScript的readProperty函数根据参数推导返回值类型?

问题需求

当部分对象的类型定义存在异常时,开发者明确知道属性的预期类型,但编译器无法识别。需要实现一个readProperty函数,能够提取符合预期类型的属性值,若实际类型与预期不符则抛出错误。同时要求编译器能根据调用时传入的typeName参数,自动推导函数的返回值类型——比如调用readProperty(someObj, "x", "number")时,编译器能识别返回值为number类型;调用readProperty(someObj, "y", "string")时,识别返回值为string类型。

原代码示例:

function readProperty<T>(obj: T, key: keyof T, typeName: "string" | "number"): string | number {
    const value = obj[key]
    if (typeof value != typeName) {
        throw new Error(`Property ${key.toString()} must be a ${typeName}`)
    }
    return value
}

const someObj = {
    x: "123",
    y: 123,
}

const x = readProperty(someObj, "x", "number") // 期望编译器识别x为number类型
const y = readProperty(someObj, "y", "string") // 期望编译器识别y为string类型
解决方案

可以通过泛型类型映射实现编译器的类型推导,将typeName参数与返回值类型关联起来:

// 建立类型名字符串到实际TypeScript类型的映射
type TypeNameToType = {
    string: string;
    number: number;
};

// 新增泛型K,约束为TypeNameToType的键类型
function readProperty<T, K extends keyof TypeNameToType>(
    obj: T,
    key: keyof T,
    typeName: K
): TypeNameToType[K] {
    const value = obj[key];
    if (typeof value !== typeName) {
        throw new Error(`Property ${String(key)} must be a ${typeName}`);
    }
    // 类型断言,告诉编译器此时value的类型符合TypeNameToType[K]
    return value as TypeNameToType[K];
}

const someObj = {
    x: "123",
    y: 123,
};

// 编译器自动推导x为number类型(运行时会抛错,因为someObj.x实际是string)
const x = readProperty(someObj, "x", "number");
// 编译器自动推导y为string类型(运行时会抛错,因为someObj.y实际是number)
const y = readProperty(someObj, "y", "string");

关键说明

  • 类型映射TypeNameToType:将"string"、"number"这些字符串字面量类型,映射到对应的TypeScript基础类型,让编译器能建立参数与返回值的类型关联。
  • 泛型K:约束typeName只能是TypeNameToType的键,确保传入的类型名字符串是合法的,同时让编译器能根据传入的K值,推导返回值为TypeNameToType[K]。
  • 类型断言:由于TypeScript的typeof操作符在类型层面无法直接关联到K,所以需要用as TypeNameToType[K]告诉编译器,经过typeof检查后,value的类型符合预期。

这样既满足了运行时的类型校验(类型不符抛错),又实现了编译时的类型推导,让编译器能准确识别返回值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 18:25:29