1

I want to pass "Interfaces" to a function. Not a specific interface, but any interfaces.

As described here, for Class, I can handle it as a type.

export type ClassType<T> = { new(...args: any[]): T };

function doSomethingWithAnyClass<T>(anyClass: ClassType<T>) {...}

My question is: Can I do the same thing for an Interface?

All Classes have constructor and they can be called a { new(...args: any[]): T } type. Then what about Interface? How do I represent an "Interface" type?

Edit

I'm writing a small DI library. When I register a dependency, I pass a pair of "class"(as token) and a "function that creates an instance of that class"(as factory). The pairs of token and factory are saved in a map structure. When resolving a dependency, I pass the token to a resolver function.

For example, let's say I have a class FileLogger and someone needs an instance of it. I want to register the dependency and resolve it from wherever it is needed. So I register a factory () => new FileLogger with a token FileLogger, and then resolve by resolve<FileLogger>(FileLogger)(It takes a generic type parameter which is redundant here but I left it to reveal that it does).

The problem is, an interface cannot be used as a token, because it is not a value. I looked for how other DI library solved this problem and found that tsyringe just uses string as token when dealing with interface.

For now, I ended up changing interfaces into abstract classes. However, I'm not happy with it and about to look for another approach.

4
  • Please consider making this code into a minimal reproducible example which shows examples of what you'd like to accept and reject being passed into doSomethingWithAnyInterface(). When you say "any class" you apparently mean "any class constructor" according to your code. I'm not sure what you mean by "any interface". The empty object type {} should be a supertype of any possible interface, but that's so wide that it only rejects null and undefined. If you're looking for something more specific than that, I'd really like to see use cases. Commented Apr 22, 2021 at 2:39
  • @jcalz I'm sorry that I missed it. I'v edited the question. Thanks. Commented Apr 22, 2021 at 21:18
  • @Potados "ended up changing interfaces into abstract classes. However, I'm not happy with it " Can you please elaborate a bit on this? Whats wrong with abstract classes? Commented Apr 23, 2021 at 1:10
  • 1
    @StupidMan As it refactored to a "class", I have to extend, not implement, it in every child class, thus forced to call super() in constructor. Every method in the abstract class must bring abstract prefix. Above all, abstract class is not suitable for my use case. I'd like to replace implementations for test, by extracting method declarations to an interface. Although abstract class can mimic an interface, it is not designed for that. What I need is interface. Commented Apr 23, 2021 at 1:44

1 Answer 1

1

Absolutely not.

Don't confuse types (interfaces, types, enums, etc) with values (boolean, string, object, array, function, etc).

Values can be arguments and each value has a type but an argument cannot be a type.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.