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

如何基于函数参数实现TypeScript对象值类型收窄?

解决方法

方法一:用函数重载实现精准类型推断

直接为不同的FilterName参数定义对应的返回类型,让TypeScript能自动匹配输入和输出的类型关系:

export enum FilterName {
  Date = 'date',
  State = 'state',
}

export enum FilterField {
  CreatedAtStartDate = 'createdAtStartDate',
  CreatedAtEndDate = 'createdAtEndDate',
  State = 'state', // 补全原代码缺失的逗号
}

export type TDateFields = {
  min: FilterField.CreatedAtStartDate;
  max: FilterField.CreatedAtEndDate;
};

// 先定义函数重载签名,明确不同参数对应的返回类型
export function getFilterField(filterName: FilterName.Date): TDateFields;
export function getFilterField(filterName: FilterName.State): FilterField.State;
// 再写函数实现
export function getFilterField(filterName: FilterName) {
  return ({
    [FilterName.Date]: {
      min: FilterField.CreatedAtStartDate,
      max: FilterField.CreatedAtEndDate,
    },
    [FilterName.State]: FilterField.State,
  }[filterName]);
}

// 调用时自动推断类型,无需断言
const dateFields = getFilterField(FilterName.Date);
dateFields.min; // 无报错,类型正确
const stateField = getFilterField(FilterName.State);
// stateField类型自动为FilterField.State

方法二:用泛型条件类型绑定输入输出

通过泛型参数关联输入的FilterName,再用条件类型返回对应结果,适合后续需要扩展更多过滤类型的场景:

export enum FilterName {
  Date = 'date',
  State = 'state',
}

export enum FilterField {
  CreatedAtStartDate = 'createdAtStartDate',
  CreatedAtEndDate = 'createdAtEndDate',
  State = 'state',
}

export type TDateFields = {
  min: FilterField.CreatedAtStartDate;
  max: FilterField.CreatedAtEndDate;
};

// 定义映射类型,把FilterName和对应的返回类型绑定
type FilterReturnType<T extends FilterName> = 
  T extends FilterName.Date ? TDateFields : FilterField.State;

export const getFilterField = <T extends FilterName>(filterName: T): FilterReturnType<T> => {
  return ({
    [FilterName.Date]: {
      min: FilterField.CreatedAtStartDate,
      max: FilterField.CreatedAtEndDate,
    },
    [FilterName.State]: FilterField.State,
  }[filterName]) as FilterReturnType<T>;
};

// 调用示例
const dateFields = getFilterField(FilterName.Date);
dateFields.min; // 类型正确,无报错
const stateField = getFilterField(FilterName.State);

注意

原代码里的FilterField枚举中,CreatedAtEndDate字段后面缺失了逗号,需要补上才能正常编译。

两种方法都能让TypeScript根据传入的FilterName自动收窄返回类型,不需要手动添加类型断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:56:04