How to implement abstract classes in Typescript?

I currently have a software which it’s comportment change depending on which operating system it’s installed (such as Windows or Linux).
So I just want to create an object fitting the operating system depending of a static config variable config.soft.type (a mere string equal to "windows" or "linux").

At program’ startup, my class need to synchronize so I put the constructor private and added an async static synchronize() method for both classes which will create and return the OperatingSystem object for Windows or Linux.

How to properly instantiate a repository for both Windows and Linux classes with their proper types ?

// index.ts
...
const { type }: 'windows' | 'linux' = config.soft;
const software = type === 'windows'
  ? new Windows.synchronize(toto, tata, tutu)
  ? new Linux.synchronize(toto, tata, tutu);
software.down();
aRandomFunction(software);
...

I would like to pass software (of type Windows | Linux) to other function (such as aRandomFunction()) and use OperatingSystem as type for software (because both Windows and Linux classes come from OperatingSystem, but I don’t know if I need to explicitely put “basic” functions (shared but overloaded by both classes) in OperatingSystemInterface)

My classes / interfaces are defined as follow:

// OperatingSystem's Interface,
abstract class OperatingSystemInterface

// The implementation of OperatingSystemInterface, I expect Windows and Linux to have `down()` method defined in OperatingSystem without redeclaring it in their interfaces
         class OperatingSystem                         implements OperatingSystemInterface

// OperatingSystem for Windows, with overloaded methods to fitt Windows's need and some more method / properties specific to Windows's class
         class Windows         extends OperatingSystem implements WindowsInterface

// OperatingSystem for Linux
         class Linux           extends OperatingSystem implements LinuxInterface

currently, I’m getting errors, such as:

error TS2420: Class 'Windows' incorrectly implements interface 'WindowsInterface'.
  Property 'synchronize' is missing in type 'Windows' but required in type 'WindowsInterface'.

8 export class Windows extends OperatingSystem implements WindowsInterface {
               ~~~~~

  src/services/OperatingSystems/types.ts:70:3
     70   synchronize(
          ~~~~~~~~~~~~
     71     client: Client,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ... 
     74     toto: string
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     75   ): Promise<WindowsInterface>;
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    'synchronize' is declared here.

But I did declare it, is it because the prototype isn’t matching ? (In the Interface I declared synchronize()‘s return type of the *Interface and in the class I return an object of the implemented class itself (Linux instead of LinuxInterface, for example), but should I import Linux in types.ts to put it as return type in LinuxInterface‘s synchronize() ? it doesn’t feel right.

Complete code:

// types.ts (where I stored my interfaces)
import { Client } from 'client';
import { Config } from 'config';

export abstract class OperatingSystemInterface {
  abstract readonly client: Client;
  abstract readonly config: Config;

  abstract down(): void;
}

export interface WindowsInterface extends OperatingSystemInterface {
  start(): Promise<void>;
  someWindowsRelatedMethod(): Promise<number>;
  anotherWindowsMethod(path: string, value: number): Promise<void>;
  synchronize(
    protected client: Client,
    protected config: Config,
    toto: string
  ): Promise<WindowsInterface>;
}

export interface LinuxInterface extends OperatingSystemInterface {
  start(): Promise<void>;
  synchronize(
    protected client: Client,
    protected config: Config,
    toto: string
  ): Promise<LinuxInterface>;
}
// OperatingSystem.ts

// Base class which `Windows` and `Linux` overload methods
export class OperatingSystem implements OperatingSystemInterface {
  public readonly informations: Information[] = [];

  constructor(
    protected client: Client,
    protected config: Config,
    toto: string,
  ) {
    this._toto = toto;
    this.client.subscribe(`${config.message}/toto/tata`);
    this.client.subscribe(`${config.message}/titi`);
  }

  get toto(): string {
    return this._toto;
  }

  down(): void {
    this.client.stop();
  }
}
// Linux.ts
import { Client } from 'client';
import { Config } from 'config';

export class Linux extends OperatingSystem implements LinuxInterface {

  private constructor(
    protected client: Client,
    protected config: Config,
    toto: string
  ) {
    super(client, config, toto);
  }

  static async synchronize(
    client: Client,
    config: Config,
    toto: string
  ): Promise<Linux> {
    const operatingSystem = new Linux(client, config, toto);
    // here some specific code to Linux
    ...
    return operatingSystem;
  }

  async start(): Promise<void> {
    this.client.on('message', (message: Message) => {
      // some Linux's specific code
    });
  }
}
// Windows.ts
import { Client } from 'client';
import { Config } from 'config';

export class Windows extends OperatingSystem implements WindowsInterface {
  // it represent the Application's permission over the Windows's API
  private windowsInfo: Config = {
    role: 'Viewer',
    isSuperAdmin: true,
  };

  private constructor(
    protected client: Client,
    protected config: Config,
    toto: string
  ) {
    super(client, config, toto);
  }

  static async synchronize(
    client: Client,
    config: Config,
    toto: string
  ): Promise<Windows> {
    const operatingSystem = new Windows(client, config, toto);
    // here some Windows' specific code
    ...
    return operatingSystem;
  }

  async start(): Promise<void> {
    this.client.on('message', (message: Message) => {
      // some Window's specific code
      this.someWindowsRelatedMethod();
    });
  }

  someWindowsRelatedMethod(): Promise<number> {
    ...
  }

  anotherWindowsMethod(path: string, value: number): Promise<void> {
    ...
  }
}