Using Typescript interface as a variable

I am working on a Node Js (TypeScript) architecture and for some reason, I want to bind my interface to a specific object. I am making a general class that is extended by other subclasses and it will have a very general code. So my code looks like

interface User {
  name: string;
}

interface Profile {
  title: string;
}

class Parent {

  name: string;
  interface: Interface; // Help required here, getting error can't use type as a variable
  
  constructor( name, interface ) {
    // Load schema and store here
    
    this.name = name
    this.interface = interface
  }

  // Though this is not correct I hope you get the idea of what I am trying to do
  
  get (): this.interface  {
    // fetch the data and return

    return data
  }

  set (data: this.interface): void {
    // adding new data
  }
}

class UserSchema extends Parent {
  // Class with custom functions for UserSchema
}

class ProfileSchema extends Parent {
  // Class with custom functions for ProfileSchema
}

// Config file that saves the configs for different modules

const moduleConfig = [
  {
    name: "User Module",
    class: UserSchema,
    interface: User
  },
  {
    name: "Profile Module",
    class: ProfileSchema,
    interface: Profile
  },
]

const allModules = {}

// Loading the modules 

moduleConfig.map(config => {
  allModules[config.name] = new config.class(
    config.name, 
    config.interface
  )
})

export allModules;

I need suggestions on how should I bind my interfaces with their respective configs. Till now I have had no luck with that.

PS: All this code is separated into their respective files.


Solution 1:

This is the use case for generics. You can even see them as "variable for types".

Instead of having an interface property in your Parent class, the latter would have a generic type:

class Parent<T> { // T is the generic type

  name: string;
  // interface: Interface; // generic is already provided at class level
  
  constructor( name ) {
    // Load schema and store here
    
    this.name = name
  }
  
  get (): T  {
    // fetch the data and return

    return data
  }

  set (data: T): void {
    // adding new data
  }
}

// Here you specify the concrete generic type
class UserSchema extends Parent<User> {
  // Class with custom functions for UserSchema
}

class ProfileSchema extends Parent<Profile> {
  // Class with custom functions for ProfileSchema
}