2

I want to create an alias for WKT strings. So I declared a type like below:

type WicketCoordinates = `${number} ${number}` | `${number} ${number} ${number}`;

Now it is simple to build alias for POINT. But when it comes to other geometries like LineString I need an string which is a comma separated of n-times repeats of type WicketCoordinates.

By that I mean I want a type that can accept all of these below:

let a = "12 34"; // One single WicketCoordinates
let b = "12 34,56 78"; // A combination of two WicketCoordinates separated by comma
let c = "12 34,56 78,90 12"; // A combination of three WicketCoordinates separated by comma
let d = "12 34,56 78, ... ,90 12"; // A combination of n-times WicketCoordinates separated by comma

So I tried declaring this type:

type WicketCommaSeperatedCoordinates = WicketCoordinates | `${WicketCoordinates},${WicketCoordinates}` | `${WicketCommaSeperatedCoordinates},${WicketCommaSeperatedCoordinates}`;

but that comes with circularly references itself error. So I tried this type:

type WicketCommaSeperatedCoordinates = {
  value:
    | WicketCoordinates
    | `${WicketCoordinates},${WicketCoordinates}`
    | `${WicketCommaSeperatedCoordinates['value']},${WicketCommaSeperatedCoordinates['value']}`;
};

But that also comes with referenced directly or indirectly in its own type annotation error.

The absolute question: Is there any way in typescript to declare a type which is an alias string made of n-times repeats of a substring?

Farhad Rad
  • 563
  • 2
  • 15
  • Don't think that's possible, as your union type will be literal and by self-referencing itself will lead to recursion (which is what the error is about). It will have a type definition of infinite length. – Terry Sep 12 '22 at 13:04
  • @Terry How infinity becomes a problem since the ```type X = `${number}`;``` is also infinite but accepted? – Farhad Rad Sep 12 '22 at 13:06
  • That's not infinite. That's simply a literal type. However your case you need to account for arbitrary number of comma separated numbers that cannot be represented by a primitive literal type. – Terry Sep 12 '22 at 13:07
  • @FarhadRad are you looking for something like [this](https://catchts.com/even-length#recursive_pattern) , [this](https://stackoverflow.com/questions/70718896/how-do-i-define-a-typescript-type-with-a-repeating-structure#answer-70720063) ? – captain-yossarian from Ukraine Sep 12 '22 at 13:25
  • [Here](https://tsplay.dev/Wo52PN) you have a plyagorund – captain-yossarian from Ukraine Sep 12 '22 at 13:34
  • @Terry in terms of infinity, you are right, but you can create big enough union type. For instance, you can create a type with 100 unions, where each element is bigger by one. – captain-yossarian from Ukraine Sep 12 '22 at 13:36
  • Yes, but you cannot account for all use-cases: i.e. any arbitrary number of comma separated numbers – Terry Sep 12 '22 at 13:52
  • @Terry I only can create maximum of allowed size union, which might be enough in some cases. But it still have a size. – captain-yossarian from Ukraine Sep 12 '22 at 14:09
  • 1
    There is no *specific* type in TypeScript that works this way; you can write a *generic* type constraint and helper function which works for arbitrary lengths like [this](https://tsplay.dev/wXjBDm), at the expense of making everything that handles this type generic. Does that address your question? If so I can write up an answer explaining; if not, what am I missing? (Please mention @jcalz if you want me to be notified of a reply) – jcalz Sep 12 '22 at 14:32

0 Answers0