'Implement interface with the type of a subclass in typescript

How can I implement the interface below in Typescript, avoiding the commented errors?

These are the classes imported from angular:

This is base class which is defined in the interface:

export declare abstract class LocationStrategy {
  abstract path(includeHash?: boolean): string;
  abstract prepareExternalUrl(internal: string): string;
  abstract pushState(state: any, title: string, url: string, queryParams: string): void;
  abstract replaceState(state: any, title: string, url: string, queryParams: string): void;
  abstract forward(): void;
  abstract back(): void;
  abstract onPopState(fn: LocationChangeListener): void;
  abstract getBaseHref(): string;
  static ɵfac: ɵngcc0.ɵɵFactoryDef<LocationStrategy, never>;
}

This is the class used in the implementation of the interface

export declare class PathLocationStrategy extends LocationStrategy {
  private _platformLocation;
  private _baseHref;
  constructor(_platformLocation: PlatformLocation, href?: string);
  onPopState(fn: LocationChangeListener): void;
  getBaseHref(): string;
  prepareExternalUrl(internal: string): string;
  path(includeHash?: boolean): string;
  pushState(state: any, title: string, url: string, queryParams: string): void;
  replaceState(state: any, title: string, url: string, queryParams: string): void;
  forward(): void;
  back(): void;
  static ɵfac: ɵngcc0.ɵɵFactoryDef<PathLocationStrategy,[null, { optional: true }]>;
  static ɵprov: ɵngcc0.ɵɵInjectableDef<PathLocationStrategy>;
}

My code:

I really need to provide types in the implementations, which will be used as tokens. The environment constant is correct, but I need to create several similar ones, so I want to create an interface for it.

So what I need is to correctly infer the IEnvironment interface without modifying locationStrategy: PathLocationStrategy in the implementation.

import { LocationStrategy, PathLocationStrategy } from '@angular/common';

export interface IEnvironment {
  production: boolean;
  locationStrategy: LocationStrategy;
  // This is just a test trying to infer what the interface should look like.
  locationStrategy1: typeof LocationStrategy;
}
const environment: IEnvironment = {
  production: false,

   // Type 'typeof PathLocationStrategy' is missing the following properties from type
   // 'LocationStrategy': path, prepareExternalUrl, pushState, replaceState, and 4 more.ts(2740)
  locationStrategy: PathLocationStrategy, 

   // Type 'typeof PathLocationStrategy' is not assignable to type 'typeof LocationStrategy'.
   // Types of construct signatures are incompatible.
   // Type 'new (_platformLocation: PlatformLocation, href?: string | undefined)
   // => PathLocationStrategy' is not assignable to type 'abstract new () => LocationStrategy'.ts(2322)
  locationStrategy1: PathLocationStrategy,
};

Typescript Playground



Solution 1:[1]

Below is the solution I found.

// @angular/core
export declare const Type: FunctionConstructor;

export declare interface Type<T> extends Function {
    new (...args: any[]): T;
}

Solution:

import { LocationStrategy } from '@angular/common';
import { Type } from '@angular/core';

export interface IEnvironment {
  production: boolean;
  locationStrategy: Type<LocationStrategy>;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alex Parloti