Dmitry Ivanov
Dmitry Ivanov

Reputation: 94

How to receive a type of each Record member in typescript?

I google the answer but still haven't found it. So, I have to post it here.

The problem is pretty simple:

Let's say I have a Record of any Abstract class.

const record = Record<string, Model>

And I also have several implementations of my model:

class A extends Model {
  foo() {
    return 'foo';
  }
}

class B extends Model {
  bar() {
    return 'bar';
  }
}

and then I store my models in my record:

record.classA = new A();
record.classB = new B();

As we can see, properties in my record are dynamic.

So, the question is: Is that possible to get a type of each key and all of the keys of my model?

For example, I want to have something like this:

function get(key: string) {
  return record[key]; //Here I expect to receive a correct type (for example class A or class B regarding the key)
}

And another question is that possible to get all existing keys when I hit enter after "record."?

I read about function overloading but could be another solution or can I dynamically overload my functions? I want to create a module structure for my app.

Thanks a lot!

Regards, Dmitry

Upvotes: 0

Views: 656

Answers (1)

Akxe
Akxe

Reputation: 11495

Typescript is a staticaly-typed language. That means that if you define record as Record<string, Model>. All of its keys will always be of type Model.

If you want to have a more complex type. You should define it either using generic or ahead of time.

const record = {
  classA: new A(),
  classB: new B(),
}

Generic would require a wrapper

class RecoldHolder<T extends Record<string, Model>> {
  record: T;

  get<K extends keyof T>(key: K): T[K] {
    return this.record[key];
  }
}

PS: Do not ever use keywords as function names, you will encounter really strange behaviours at times. Use getter, instead of get, etc.

Upvotes: 1

Related Questions