Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript: Declare type of a keyof a generic object param

I am trying to create a custom sort function for an array of objects of varying types. I would like the function to be generic enough to work for many types that contain atleast one string property.

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
}

Can I declare the type of the ‘field’ param to be the keyof any object that is of type string?

For example, the function above won’t work if Record has a number property because localCompare is a string function.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

Solution

This worked for me, edited from caTS’ answer:

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) => ...
}

>Solution :

You could define a type to get the keys that have a specific type like this:

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

and then you can use it in your function:

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

Note that I renamed Record to MyRecord since Record is already a built-in type.

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading