如何在Typescript中实现抽象类?

问题描述 投票:0回答:1

我目前有一个软件,其功能会根据安装的操作系统而变化(例如

Windows
Linux
)。 所以我只想创建一个适合操作系统的对象,具体取决于静态配置变量
config.soft.type
(仅等于
"windows"
"linux"
的字符串)。

在程序启动时,我的类需要同步,因此我将构造函数设为私有,并为两个类添加了

async static synchronize()
方法,该方法将为 Windows 或 Linux 创建并返回
OperatingSystem
对象。

如何使用正确的类型正确实例化

Windows
Linux
类的存储库?

// 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);
...

我想将

software
(类型为
Windows | Linux
)传递给其他函数(例如
aRandomFunction()
)并使用
OperatingSystem
作为
software
的类型(因为
Windows
Linux
类都来自
OperatingSystem
,但我不知道是否需要明确地将“基本”函数(两个类共享但重载)放在
OperatingSystemInterface

我的类/接口定义如下:

// 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

目前,我遇到错误,例如:

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.

但我确实声明了,是因为原型不匹配吗? (在接口中,我声明了 *Interface 的

synchronize()
的返回类型,并且在类中,我返回了已实现类本身的对象(例如,Linux 而不是 LinuxInterface),但是我应该在
Linux 中导入 
types.ts
 吗? 
将其作为返回类型放入
LinuxInterface
synchronize()
中?感觉不太对。

完整代码:

// 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> {
    ...
  }
}
javascript typescript inheritance overloading
1个回答
0
投票

我可以看到一些问题:

  1. 静态成员属于
    class
    ,而不是
    interface

错误信息正确:

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

您的

WindowsInterface
接口声明了
synchronize()
方法,但您已在类上将其作为静态方法实现。

因此,从编译器的角度来看,您的类缺少

synchronize()
方法,并且它给您带来了该错误。

不可能在接口上定义静态成员;静态成员属于类,而不是接口。

考虑到您在其他地方如何使用该功能,您应该从界面中删除

synchronize()


  1. 您的
    synchronize()
    功能的使用不正确

您的静态

synchronize()
函数已经实例化您的类(即
new
)并返回新实例。 基本上,这就像您试图做
new new Windows(...)
,这是不正确的。

并且您的

synchronize()
函数正在返回一个 Promise - 您将需要链接该 Promise 或使用
await
来“解开”该 Promise 以访问其中的值。

static async synchronize(
    client: Client,
    config: Config,
    toto: string
): Promise<Windows> {
   ^^^^^^^^^^^^^^^^ - you're returning a promise here
  
    const operatingSystem = new Windows(client, config, toto);
                            ^^^^^^^^^^^ - you're constructing the instances here
    // here some Windows' specific code
    ...
    return operatingSystem;
}
// index.ts
...
const { type }: 'windows' | 'linux' = config.soft;
const software = type === 'windows'
  ? new Windows.synchronize(toto, tata, tutu)
    ^^^^^^^^^^^ - this is a `Promise<Windows>`
    // don't use `new` here
    // you'll need to "unwrap" the promise to access the Windows instance
  ? new Linux.synchronize(toto, tata, tutu);
    ^^^^^^^^^ - same error here

// You need to chain the promise or use `await` to access the value inside the `software` promise
software.down();
aRandomFunction(software);

如果您可以使用顶级

await
,那么这是最简单的代码版本:

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

software.down();
aRandomFunction(software);
© www.soinside.com 2019 - 2024. All rights reserved.