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

TypeScript泛型函数如何限定参数为值为字符串类型的对象键?

解决TypeScript中matchBy函数的类型断言问题

我正在编写一款带组合式参数的通用过滤函数matchBy,它会返回一个匹配器函数,用于将对象<T>的指定属性(propertyName: keyof T)与字符串术语(term: string)进行比较。

原代码如下:

type Predicate<T> = (item: T) => boolean
type ConditionedPredicate<T, C> = (condition: C) => Predicate<T>

export const matchBy = <T>(propertyName: keyof T): ConditionedPredicate<T, string> => (term) => (item) => {
  const propertyValue = item[propertyName] as string
  const substringRegex = new RegExp(term, 'i')

  return Boolean(propertyValue.match(substringRegex))
}

当前问题是必须将propertyValue断言为string类型,请问如何定义propertyName的类型,使其仅允许T中值类型为string的键,从而避免该类型断言?


解决方案

通过自定义条件类型提取T中值类型为string的键,以此约束propertyName的参数类型,让TypeScript自动推断属性值的类型,无需手动断言。

  1. 定义StringKeys<T>类型,筛选出T中所有值为string类型的键:
type StringKeys<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T]

这个类型的逻辑是:遍历T的所有键K,如果T[K]是string类型则保留键名K,否则设为never;最后通过[keyof T]取出所有有效键的联合类型。

  1. 修改matchBy函数的propertyName参数类型为StringKeys<T>:

修改后的完整代码:

type Predicate<T> = (item: T) => boolean
type ConditionedPredicate<T, C> = (condition: C) => Predicate<T>

type StringKeys<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T]

export const matchBy = <T>(propertyName: StringKeys<T>): ConditionedPredicate<T, string> => (term) => (item) => {
  const propertyValue = item[propertyName]
  const substringRegex = new RegExp(term, 'i')

  return Boolean(propertyValue.match(substringRegex))
}

此时item[propertyName]会被TypeScript自动推断为string类型,彻底消除了类型断言的必要。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:03:12