#Typing a difference(arr1, arr2, comparator) function

29 messages · Page 1 of 1 (latest)

tiny arrow
#

Hey all, I'm trying to code a basic difference() function that can accept one of three kinds of comparators:

  • Nothing (compare elements directly)
  • String (key of both arr1 and arr2)
  • Compare function (gets items from both arrays)

It looks something like this and I'm getting errors on using string to index the generics. Could anyone help me create a type from a key from both T and U? Thanks!

digital moatBOT
digital moatBOT
#
Ascor8522#7606

Preview:```ts
type CmpFn<T, U> = (x: T, y: U) => boolean

export function difference<T, U>(
arr1: T[],
arr2: U[]
): T[]
export function difference<T, U>(
arr1: T[],
arr2: U[],
comparator: keyof T & U
): T[]
export function difference<T, U>(
arr1: T[],
arr2: U[],
comparator: (x: T, y: U) => boolean
): T[]
...```

cunning lily
#

multiple things

#
  1. it's probably easier to use function overload in this case, since you already have the signatures figured out
#

it might be more verbose, but on the other hand it's cleaner than that previous union you had

#
  1. also, I moved the default comparasion function to some variable, to make it a bit cleaner
#
  1. I used a switch instead of that ternary operator, it's probably easier to see what's happening as well
#
  1. the string type in your difference was wrong, it's not just any string you accept, but one that is a key on the objects contained in the array, so I changed it to keyof T & U
#

you could also set it to keyof T | U of you only want to allow for the key to be present on 1 object out of the 2, and if you don't mind comparing a value with undefined

#

@tiny arrow

tiny arrow
#

Ah yea, this is actually a good case for function overloading!

#

Also the switch (true) is some warlock sh*t

#

Any specific reason why the x value needs to be cast as unknown first before being compared to y?

#

Oh it’s because it doesn’t find any overlap between T and U as different arrays. Is casting something to unknown for comparison between generics the usual approach?

cunning lily
#

as you said

#

Is casting something to unknown for comparison between generics the usual approach?
not really, but sometimes it's one of the few options left when comparing elements of different types

#

imo it shouldn't be a TS error, but a warning

tiny arrow
#

Is there a way to use extends to guarantee the comparison is of the same type?

cunning lily
#

I guess

#

but I'm not sure there is a real need for generics in this case

#

it does not provide any additional benefits

#

you could just type both your arrays as unknown[] and it would work just fine

#

wait, no, you still need the type for the keyof 🤔

#

and I think T extends U, U extends T won't work 🤔

tiny arrow
#

Yea I was thinking a third generic V for representing the value

#

Honestly might just go with unknown and not have typing on the key string comparator for ease of maintenance

#

Thank you for the help!