Skip to content

Proper constructor type hinting possible? #67

@TaylorBenner

Description

@TaylorBenner

Is it possible to get proper constructor type hinting from something like the following?

/**
 * A helper type that defines generic arguments to a constructor.
 */
export type GenericArgs<T> = Record<PropertyKey, any> & T;

/**
 * @class
 */
export class LoggerAware {
  /**
   * @property { Types.Logger } logger
   * @protected
   * @readonly
   */
  protected readonly logger: Types.Logger;

  /**
   * @param { Types.GenericArgs & { logger: Types.Logger }} args 
   * @public
   * @constructor
   */
  public constructor(args: Types.GenericArgs<{ logger: Types.Logger }>) {
    this.logger = args.logger;
  };
};

/**
 * @class
 */
export class EmitterAware<T extends Types.EventMap> {
  /**
   * @property { Types.TypedEventEmitter<T> } emitter
   * @protected
   * @readonly
   */
  protected readonly emitter: Types.TypedEventEmitter<T>;

  /**
   * @param { Types.GenericArgs & { emitter?: Types.TypedEventEmitter }} args 
   * @public
   * @constructor
   */
  public constructor(args: Types.GenericArgs<{ emitter?: Types.TypedEventEmitter<T>}>) {
    this.emitter = args.emitter || new EventEmitter() as Types.TypedEventEmitter<T>;
  };
};

/**
 * @class
 */
export class CacheAware {
  /**
   * @property { Types.CacheInterface } cache
   * @protected
   * @readonly
   */
  protected readonly cache: Types.CacheInterface;

  /**
   * @param { Types.GenericArgs & { cache?: Types.CacheInterface }} args 
   * @public
   * @constructor
   */
  public constructor(args: Types.GenericArgs<{ cache?: Types.CacheInterface}>) {
    this.cache = args.cache || new MemoryCache();
  };
};

/**
 *
 */
export class Service extends Mixin(LoggerAware, CacheAware, EmitterAware) {
};

// This is very close to working.  I get inconsistent type hinting results.  
// It seems to cycle between any of the three args.
const service = new Service({ cache: '', logger: '', emitter: '' });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions