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

如何根据可选对象参数动态变更TypeScript函数返回类型

问题描述

需要实现:当传入的obj参数中存在aX属性时,返回类型才包含{a: boolean};同理bX对应b、cX对应c。但当前代码中,调用func传入仅含aX的参数后,访问test1.b不会触发TypeScript错误,不符合预期,需让返回类型随输入参数动态调整。

当前代码:

type IObjFunc = () => void

interface IObj {
    aX?: IObjFunc
    bX?: IObjFunc
    cX?: IObjFunc
}

interface IReturnData {
    a?: boolean
    b?: boolean
    c?: boolean
}

const func = (obj: IObj) => {
    const returnData: IReturnData = {}

    if (obj.aX)
        returnData.a = true
    
    if (obj.bX)
        returnData.b = true
    
    if (obj.cX)
        returnData.c = true

    return returnData
}

const test1 = func({ aX: () => undefined })

console.log(test1.a) // 正常
console.log(test1.b) // 未报错,但应该报错
解决方案

通过泛型结合映射类型实现动态返回类型,让输出严格匹配输入的属性映射关系:

type IObjFunc = () => void

// 约束输入参数只能包含aX/bX/cX这些可选属性
type InputObj = Partial<{ aX: IObjFunc; bX: IObjFunc; cX: IObjFunc }>

// 映射输入属性到输出属性的工具类型:把aX转为a,bX转为b,仅保留输入中存在的属性
type ReturnTypeFromInput<T extends InputObj> = {
    [K in keyof T as K extends `${infer P}X` ? P : never]: boolean
}

const func = <T extends InputObj>(obj: T): ReturnTypeFromInput<T> => {
    const returnData = {} as ReturnTypeFromInput<T>

    if ('aX' in obj && obj.aX) {
        (returnData as any).a = true
    }
    if ('bX' in obj && obj.bX) {
        (returnData as any).b = true
    }
    if ('cX' in obj && obj.cX) {
        (returnData as any).c = true
    }

    return returnData
}

// 测试验证
const test1 = func({ aX: () => undefined })
console.log(test1.a) // 正常
console.log(test1.b) // 触发TypeScript错误,符合预期

const test2 = func({ bX: () => undefined, cX: () => undefined })
console.log(test2.b) // 正常
console.log(test2.c) // 正常
console.log(test2.a) // 触发TypeScript错误
代码说明
  1. 泛型约束:T extends InputObj确保输入参数只能包含指定的aX/bX/cX属性,避免非法输入。
  2. 映射类型:ReturnTypeFromInput<T>利用模板字符串类型,自动将输入中的aX映射为输出的a,仅保留输入中实际存在的属性对应的输出键。
  3. 类型断言:函数内部赋值时用as any临时绕过类型检查,因为TypeScript无法自动推断动态属性的赋值逻辑,实际运行逻辑是安全的。

修改后,返回类型会严格跟随输入参数的属性变化,访问不存在的输出属性时会立即触发TypeScript错误,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 18:40:34