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

如何通过联合类型参数返回正确的动态类型?

错误原因与修复方案

错误原因

  1. 泛型T的条件类型是延迟解析的:T extends A ? returnA : returnB只有在useFunc被具体调用(比如传入'a'或'b')时才会确定具体返回类型,但在函数定义阶段,编译器无法提前确认return 'type_a'或return 'type_b'是否匹配这个动态的条件类型。
  2. 类型窄化无法关联泛型:虽然通过if (type == 'a')窄化了type的类型,但编译器无法将这种窄化关联到泛型T的条件判断上,因此无法验证返回值的类型兼容性。

修复方案

方案一:直接断言返回值为目标条件类型

明确告诉编译器返回值符合泛型条件类型,快速解决报错:

type A = 'a'
type B = 'b'

type returnA = 'type_a'
type returnB = 'type_b'

function useFunc<T extends A | B>(type: T = 'a' as T) {
    function resolveSomeByType(): T extends A ? returnA : returnB {
        if (type === 'a') {
            return 'type_a' as T extends A ? returnA : returnB
        } else {
            return 'type_b' as T extends A ? returnA : returnB
        }
    }

    return { resolveSomeByType }
}

// 测试用例
const { resolveSomeByType: resolveA } = useFunc('a')
const resultA = resolveA() // 类型自动推断为returnA ('type_a')

const { resolveSomeByType: resolveB } = useFunc('b')
const resultB = resolveB() // 类型自动推断为returnB ('type_b')

方案二:使用函数重载

通过重载签名明确不同输入对应的返回类型,让编译器更准确地进行类型推断:

type A = 'a'
type B = 'b'

type returnA = 'type_a'
type returnB = 'type_b'

function useFunc<T extends A | B>(type: T = 'a' as T) {
    // 重载签名:对外暴露的类型逻辑
    function resolveSomeByType(): T extends A ? returnA : returnB;
    // 实现签名:内部执行逻辑,类型放宽为联合类型
    function resolveSomeByType(): returnA | returnB {
        if (type === 'a') {
            return 'type_a'
        } else {
            return 'type_b'
        }
    }

    return { resolveSomeByType }
}

// 测试用例
const { resolveSomeByType: resolveA } = useFunc('a')
const resultA = resolveA() // 类型为returnA ('type_a')

const { resolveSomeByType: resolveB } = useFunc('b')
const resultB = resolveB() // 类型为returnB ('type_b')

方案三:使用类型映射表

定义输入类型到输出类型的映射关系,代码更简洁且扩展性更强:

type A = 'a'
type B = 'b'

// 定义输入与输出的类型映射
type TypeMap = {
    [A]: 'type_a',
    [B]: 'type_b'
}

function useFunc<T extends A | B>(type: T = 'a' as T) {
    function resolveSomeByType(): TypeMap[T] {
        // 利用类型断言让编译器确认返回值符合映射类型
        return type === 'a' ? 'type_a' : 'type_b' as TypeMap[T]
    }

    return { resolveSomeByType }
}

// 测试用例
const { resolveSomeByType: resolveA } = useFunc('a')
const resultA = resolveA() // 类型为'type_a'

const { resolveSomeByType: resolveB } = useFunc('b')
const resultB = resolveB() // 类型为'type_b'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:35:13