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

4
  • What is "dynamically" supposed to mean in this context? Commented Dec 21, 2020 at 20:14
  • That's it's provided as param to the method and within that method I need to create type from that. Commented Dec 21, 2020 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). Commented Dec 21, 2020 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. Commented Dec 21, 2020 at 20:41

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

4 Comments

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?
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 minimal reproducible example 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.
Ok I have change a question and example as well
Thank you so much bro!!! It's what I have been looking for!!! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.