javascripttypescripttypes

TypeScript definitions for `zip` and `zipObj` functions


I would like to combine/reuse the type definitions for the following functions.

const zip = <T, K>(arr1: readonly T[], arr2: readonly K[]): Array<[T, K]> => arr1.map((k, i) => [k, arr2[i]])

const zipObj = <T extends string, K>(arr1: readonly T[], arr2: readonly K[]): { [key: string]: K} => 
  Object.fromEntries(zip(arr1, arr2))

// usage
const names = ['bob', 'sally', 'dave'] as const
const ages = [50, 40, 30] as const

const myEntries = zip(names, ages) // [['bob', 50], ['sally', 40], ['dave', 30]]
const myObj = zipObj(names, ages) // { 'bob': 50, 'sally': 40, 'dave': 30 }

How could I define type GeneralZipFunction in a way that re-uses T and K but allows me to A) override the return type and B) specify that T needs to extend string.

Ideally I could write:

const zip: GeneralZipFunction<some specifiers go in here> = // zip implementation
const zipObj: GeneralZipFunction<some specifiers go in here> // zipObj implementation

Solution

  • I'm pretty sure you can't. TypeScript doesn't allow abstracting over type parameters, you generally have to declare them explicitly. I don't really see what advantage you'd gain by sharing types here.

    The closest things I could think of are