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

React Hook中如何根据传入type实现严格类型推断?

修复React Hook useFilterSelector的TypeScript类型推断问题

要解决这个类型推断问题,核心是让TypeScript明确传入的type参数与返回的过滤器类型之间的一一对应关系。下面提供两种可靠的解决方案:

基础类型定义

先明确过滤器类型和类型映射关系,这是后续方案的基础:

// 定义具体的过滤器类型
type ProductFilter = {
  type: 'product';
  filterProducts: (ids: string[]) => void;
};

type ContentFilter = {
  type: 'content';
  filterContent: (tags: string[]) => void;
};

// 建立字符串类型到过滤器类型的映射
type FilterTypeMap = {
  product: ProductFilter;
  content: ContentFilter;
};

方案1:使用函数重载

函数重载可以直接为不同的输入参数指定对应的返回类型,TypeScript会自动匹配对应的重载规则,实现精准的类型推断:

// 重载声明:明确不同type对应的返回类型
function useFilterSelector(type: 'product'): ProductFilter;
function useFilterSelector(type: 'content'): ContentFilter;

// 函数实现:返回联合类型即可
function useFilterSelector(type: 'product' | 'content'): ProductFilter | ContentFilter {
  if (type === 'product') {
    return { 
      type: 'product', 
      filterProducts: (ids) => { /* 实际逻辑 */ } 
    };
  } else {
    return { 
      type: 'content', 
      filterContent: (tags) => { /* 实际逻辑 */ } 
    };
  }
}

// 调用时类型推断完全正确
const productFilter = useFilterSelector('product');
productFilter.filterProducts(['prod-1', 'prod-2']); // 无类型错误

const contentFilter = useFilterSelector('content');
contentFilter.filterContent(['news', 'tech']); // 无类型错误

方案2:泛型 + 类型映射

通过泛型约束type参数为FilterTypeMap的键,直接返回映射对应的类型,让TypeScript根据传入的具体type值推断返回类型:

function useFilterSelector<T extends keyof FilterTypeMap>(type: T): FilterTypeMap[T] {
  // 这里需要类型断言,因为TypeScript无法在分支中自动推断T的具体值
  if (type === 'product') {
    return { 
      type: 'product', 
      filterProducts: (ids) => { /* 实际逻辑 */ } 
    } as FilterTypeMap[T];
  } else {
    return { 
      type: 'content', 
      filterContent: (tags) => { /* 实际逻辑 */ } 
    } as FilterTypeMap[T];
  }
}

// 类型推断效果与重载一致
const productFilter = useFilterSelector('product'); // 类型为ProductFilter
const contentFilter = useFilterSelector('content'); // 类型为ContentFilter

为什么原条件类型会得到unknown?

你之前尝试的条件类型失效,大概率是因为:

  • 函数参数的type没有被约束为具体的字面量类型,导致条件类型无法精准匹配分支
  • 在函数实现中,TypeScript无法将分支返回值与条件类型的结果关联起来,最终导致类型收窄失败,退化为unknown或联合类型

上述两种方案都通过明确参数与返回值的类型绑定,解决了这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:07:21