0

I have a Market class which has only 1 parameter: name.

class Market {
  name: string

  constructor(name: string) {
    this.name = name
  }
}

I then have a Markets class which is a static collection of several markets.

class Markets {
  static M1 = new Market("M1M")
  static M2 = new Market("M2M")
  static M3 = new Market("M3M")
}

I was wondering if there was a way to extract all name parameters from all markets into a type, such that the type would look something like this:

type MarketNames = "M1M" | "M2M" | "M3M"

I know about the keyof operator, is it the way?

Thanks.

6
  • TS keys of type. Commented Sep 28, 2022 at 20:34
  • @caTS I have read it, but don't know how to apply it in order to get the value. Commented Sep 28, 2022 at 20:35
  • @caTS In the answer you've attached he is trying to get the keys whilst I'm trying to get the values. Commented Sep 28, 2022 at 20:38
  • Ah... I did not read that closely. I assumed you got the result from the key names... Commented Sep 28, 2022 at 20:42
  • @Riccardo You're not just trying to get the values, you're trying to get the parameters used to instantiate the static values. That's much more difficult, and doesn't line up with the title of the question. (I'd call it impossible unless you change the definition of Market to be generic based on the string literal passed in, and at that point I think it makes sense to define the constants elsewhere and programmatically create the static members.) Commented Sep 28, 2022 at 20:42

1 Answer 1

1

For this to work, your class has to be generic, so we can "extract" the generic out of it later:

class Market<Name extends string> {
  name: Name;

  constructor(name: Name) {
    this.name = name
  }
}

Then we create our type to extract the names:

type NamesOfMarkets<T> = Extract<T[keyof T], Market<string>> extends Market<infer N> ? N : never;

We're filtering out the values of the class for only Markets, then we infer the name and return that.

Note: you must pass the class as typeof Markets to get the constructor type. Markets by itself is simply a class instance.

Playground

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

4 Comments

Thanks! Just checked your GitHub. Where did you learn types so well? Do you have any resource to suggest?
You pick up a few things when using a language for some time. I didn't really use any resources, but I found a really good one that is unfortunately a work-in-progress: type-level-typescript.com. Also check out Typescript Deep Dive.
Last clarification, what is the purpose of typeof Markets? To gain access to the static methods?
Yes, basically.

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.