#Creating a Map<Constructor implements Interface, Instance>

23 messages · Page 1 of 1 (latest)

charred abyss
#

Hi, I'm having trouble creating a map whose keys are a constructor (the class) and values are an instance of said class. Aditionally I also want to require the keys to implement a specific instance.

This is what I tried: (playground link) but it doesn't correctly error if the set value isn't an instance of the key, and when getting it doesn't return an instance of the key, but rather an instance of the interface. I'm not sure what I'm doing wrong here.

midnight sailBOT
#
amgelo563#0

Preview:```ts
interface Interface {
prop: string
}

type Constructor<T = Interface> = new (
...args: any[]
) => T

type ConstructorInstanceMap<
C extends Constructor = Constructor

= Map<C, InstanceType<C>>

class Foo implements Interface {
public prop: string = "foo"
...```

azure ruin
#

maps are homogenous, they don't have different mappings for each speciifc key

charred abyss
#

what could I do in my case then?

#

it seems that overriding the get method works but it's not really the ideal situation I guess

type ConstructorInstanceMap<C extends Constructor = Constructor> = Omit<Map<C, InstanceType<C>>, 'get'>
  & { get<const C extends Constructor = Constructor>(k: C): InstanceType<C> };
pulsar crown
#

What's the use case?

#

Some sort of singleton creation?

charred abyss
#

yeah, kind of like a service storage

pulsar crown
#

I need to know how you want to use it to make a suggestion

#

My first though it something like

class Foo {}
class Bar {}

const services = {
  foo: new Foo,
  bar: new Bar
}

services.foo
services.bar

But without knowing what you're trying to achieve, can't really see the logic in making it more complicated than this.

charred abyss
#

I'm making a file system for reading/parsing configuration files for my project, I already have the FileProcessors that do all that for an individual file, and I want to create a "repository" where I can then get those processors from their class, and register them as well dynamically

#

the easier solution would be to basically just wrap a map, but I'm struggling on the type of said map

pulsar crown
#

hmm

#

You could probably use a Map and just don't worry that it's not type checked

#

Seems unlikely that you can mess up that bit of code

charred abyss
#

yeah that's fair, also the consumer wouldn't know it actually uses a map

#

I think I'll just stick to that for now since the alternative to override every method doesn't seem practical lol

pulsar crown
#
function registerConfig(Class: new () => object) {
  map.set(Class, new Class)
}

If you're doing something like this and it's all wrapped in functions, then yeah

floral moth
heady helm
#

Because signatures like keys, values, entries all have to be changed as well.

#

Well maybe not keys/values if your underlying Map<K, V> already has matching K/V.

charred abyss