网站搜索

Typescript:声明泛型对象参数的键类型


我正在尝试为一个包含不同类型对象的数组创建自定义排序函数。我希望这个函数足够通用,可以适用于包含至少一个字符串属性的多种类型。

interface Record {
  id: string
  name: string
}


const sortStr = (field: keyof Record, reverse: boolean) => {
  return (a: Record, b: Record) =>
    a[field] !== "" && b[field] !== ""
      ? (reverse ? -1 : 1) *
        a[field].localeCompare(b[field], undefined, { sensitivity: "base" })
      : a[field] !== "" && b[field] === ""
      ? -1
      : a[field] === "" && b[field] !== ""
      ? 1
      : 0
}

我可以将 'field' 参数的类型声明为任何类型为字符串的对象的 keyof 吗?

例如,如果 Record 有一个数字属性,上面的函数将无法工作,因为 localCompare 是一个字符串函数。

interface Record {
  id: string
  name: string
  user: number
}

解决方案

这对我有用,是根据caTS的回答编辑的:

type KeysOfType<O, T> = {
  [K in keyof O]: O[K] extends T ? K : never
}[keyof O]

const sortStr = (field: KeysOfType<any, string>, reverse: boolean) => {
  return (a: any, b: any) => ...
}

答案#1

你可以定义一个类型来获取具有特定类型的键,如下所示:

type KeysOfType<O, T> = {
    [K in keyof O]: O[K] extends T ? K : never
}[keyof O];

然后你可以在你的函数中使用它:

const sortStr = (field: KeysOfType<MyRecord, string>, reverse: boolean) => {

请注意,我将 Record 重命名为 MyRecord,因为 Record 已经是一个内置类型。

操场