react-id-generator icon indicating copy to clipboard operation
react-id-generator copied to clipboard

Smarter TS types so don't have to do undefined check

Open TSMMark opened this issue 3 years ago • 2 comments

Hi, thanks for your work on this library, it's really handy.

The return type of useId is string[] https://github.com/Tomekmularczyk/react-id-generator/blob/97e5bf6d8df59aa21363ea314ca612d22966cb50/src/useId.ts#L20

This is accurate, but it would be more helpful if it could instead return a tuple (e.g. [string]), which contains the number of string elements, as determined by the count argument (default: 1)

Screen Shot 2022-11-10 at 3 48 14 PM

Notice how TS thinks it can be string | undefined. This is because when TS sees string[], it thinks it may have length 0.

if a tuple is used instead, e.g. [string], you do not have this issue:

Screen Shot 2022-11-10 at 3 50 59 PM

TSMMark avatar Nov 10 '22 20:11 TSMMark

hey @TSMMark the typings are automatically generated, but you have a valid point. Let me come up with something. Feel free to create a PR as well!

Tomekmularczyk avatar Dec 04 '22 13:12 Tomekmularczyk

gotcha

One solution I have thought of but haven't tested could be using the type extends ternary like https://www.typescriptlang.org/docs/handbook/2/conditional-types.html

type TReturn<TCount extends number> = TCount extends 1
  ? [string]
  : TCount extends 2
    ? [string, string]
    : TCount extends 3
      ? [string, string, string]
      : string[] // fallback for when count is too high

function htmlId<TCount extends number = 1>(count: TCount): TReturn<TCount> {
 // ... etc
}

There is probably a better way to say "tuple of length TCount, filled with strings" but idk how to do that. Should just ask ChatGPT honestly lol

TSMMark avatar Dec 05 '22 17:12 TSMMark