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

TypeScript中函数参数推断为never但传入参数合法的类型问题求解

解决TypeScript泛型工厂函数与参数的类型匹配问题

问题分析

你的代码中,test函数的泛型T受boolean约束,TypeScript推断factory()返回值时会将其解析为A | B联合类型。由于A和B的参数类型'A'与'B'无交集,TypeScript会把联合函数的参数类型推断为never,导致f(funcArg)报错——尽管funcArg的ArgType<T>理论上和f的参数类型完全对应,但TypeScript无法自动关联两者的泛型依赖关系。

解决方案

核心思路是让factory()的返回类型与泛型T保持显式条件关联,避免被解析为无差别的联合类型,以下是两种可行方案:

方案1:显式定义useComposable的返回类型

将useComposable的返回类型抽离为泛型条件类型,让TypeScript保留T与返回函数类型的绑定关系:

type A = (arg: 'A') => void
type B = (arg: 'B') => void

const a: A = (arg: 'A') => { }
const b: B = (arg: 'B') => { }

// 显式定义返回类型的泛型条件
type UseComposableReturn<T extends boolean> = {
  factory: () => T extends true ? A : B;
};

function useComposable<T extends boolean>(arg: T): UseComposableReturn<T> {
  return {
    factory: () => (arg ? a : b) as T extends true ? A : B,
  };
}

type ArgType<R extends boolean> = Parameters<
  ReturnType<ReturnType<typeof useComposable<R>>['factory']>
>[0]

function test<T extends boolean>(composableArg: T, funcArg: ArgType<T>) {
  const { factory } = useComposable(composableArg);
  const f = factory();
  f(funcArg); // 类型检查通过
};

// 合法调用
test(true, 'A')
// 预期不合法(TypeScript会报错)
test(true, 'B')

方案2:在test函数中显式关联类型

如果不想修改useComposable,可以在test内部通过泛型条件类型明确f的类型,让TypeScript识别它与funcArg的匹配关系:

type A = (arg: 'A') => void
type B = (arg: 'B') => void

const a: A = (arg: 'A') => { }
const b: B = (arg: 'B') => { }

function useComposable<T extends boolean>(arg: T) {
  type MyType = T extends true ? A : B

  function factory(): MyType {
    return (arg ? a : b) as MyType
  }

  return { factory }
}

type ArgType<R extends boolean> = Parameters<
  ReturnType<ReturnType<typeof useComposable<R>>['factory']>
>[0]

function test<T extends boolean>(composableArg: T, funcArg: ArgType<T>) {
  const { factory } = useComposable(composableArg);
  // 显式关联泛型T与f的类型
  type FuncType = T extends true ? A : B;
  const f = factory() as FuncType;
  f(funcArg); // 类型检查通过
};

// 合法调用
test(true, 'A')
// 预期不合法(TypeScript会报错)
test(true, 'B')

原理说明

两种方案都是通过保留泛型条件类型的关联性,避免TypeScript将factory()的返回值解析为A | B联合类型。当类型系统能明确f的类型是基于T的条件分支时,就能自动匹配funcArg的ArgType<T>,从而通过类型检查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 03:12:10