1

Is there way to dynamically create a string literal type from a string, other than making an array from the string and then extracting its type using typeof, as shown in this answer?

const url = 'text'
const URL = [url]
type P = (typeof URL)[number];

EDIT What I am trying to achieve is build, a method which based on the given string(endpoint URL) will be able extract required by that endpoint params which I need to provide.

export type ExtractRouteParams<T> = string extends T
? Record<string, string>
: T extends `${infer _Start}:${infer Param}/${infer Rest}`
? { [k in Param | keyof ExtractRouteParams<Rest>]: string }
: T extends `${infer _Start}:${infer Param}`
? { [k in Param]: string }
: {};

ExtractRouteParams is a type which based on the given string return my type which defined what kind of params are needed. Its works completely fine when I use it like that.

type Test = ExtractRouteParams<'actions/:actionId/test/:testId'>

But I would like it to work more dynamicaly. I have create an factory URL method within which I want to create type based on the URL provided as parameter. That method return generic class (Based on that dynamic type) which contain method to create url.

export function urlFactory(url: string) {
  type P = typeof url;
  return new InterpolateUrl<P>();
}

class InterpolateUrl<T extends string> {
  url(params: ExtractRouteParams<T>): void {

  }
}

const endpoints = {
    endpoint: urlFactory(
       'actions/:actionId/test/:testId'
    )
};

Unfortunately InterpolateUrl class method url does not properly points required params. In compared, type Test does.

Here playground

Stefan
  • 1,431
  • 2
  • 17
  • 33
  • What is "dynamically" supposed to mean in this context? – Aplet123 Dec 21 '20 at 20:14
  • That's it's provided as param to the method and within that method I need to create type from that. – Stefan Dec 21 '20 at 20:17
  • Not sure I follow. TypeScript is a *static* type checker, but you want it to react to dynamic parameters? Even the question you linked explains that this is not possible (see the comments). – str Dec 21 '20 at 20:35
  • Maybe I wrote it wrong. At the moment of starting the app the URL is defined as in the example, but I have a few of them and would like to extract type individually for all of the predefined values within that method. Here is an playground. I would like to extract properly all the parameters needed by my endpoint based on it's URL using custom type. Link to playground -> shorturl.at/evzCS. – Stefan Dec 21 '20 at 20:41

1 Answers1

1

UPDATE

Given your updated question and example, it looks like all you want is for your urlFactory() function to itself be generic. The compiler doesn't really look at a specific type like string and treat it generically because the output type would be better for you; you have to tell the compiler when you want generics:

export function urlFactory<P extends string>(url: P) {
  return new InterpolateUrl<P>();
}

Once you do that, things works as desired, I think:

console.log(endpoints.endpoint.url({
  actionId: "hey",
  testId: "you"
})); // okay

console.log(endpoints.endpoint.url({
  // error!
  // Type '{}' is missing the following properties from type 
  // '{ actionId: string; testId: string; }': actionId, testId
}))

Playground link to code


Original answer

You can use the TypeScript typeof type query operator directly on url without having to make an intervening array:

const url = 'text'
type P = typeof url;
// type P = "text"

Playground link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360
  • Can you look at my comment under my answer and here at my playground whether thing which I am trying to achieve is even possible -> shorturl.at/evzCS? – Stefan Dec 21 '20 at 20:48
  • 1
    Hmm, that's a bunch of code and yet nothing obvious that jumps out as expected vs actual behavior; could you pare that down to a [mcve] that demonstrates your issue and only your issue? And ideally you'd put any such code in the text of your question and not just in external links. – jcalz Dec 21 '20 at 20:53
  • Ok I have change a question and example as well – Stefan Dec 21 '20 at 21:13
  • Thank you so much bro!!! It's what I have been looking for!!! :) – Stefan Dec 21 '20 at 21:25