在打字稿中的类中创建具有未知参数的方法

Posted

技术标签:

【中文标题】在打字稿中的类中创建具有未知参数的方法【英文标题】:Creating a method with unknown parameters in a class in typsescript 【发布时间】:2021-10-02 10:31:07 【问题描述】:

我和我的团队目前正在使用 discordjs 和 typescript 开发一个不和谐机器人项目。我们制作了一个像这样工作的事件处理程序, 主文件滚动通过文件夹events\ 并找出具有.js.ts 扩展名的文件。然后导入文件。

例如,ErrorEvent 文件如下所示,

// file: src\events\ErrorEvent.ts

import CustomClient from "../libs/customClient";
import Event from "../libs/structure/event/Event";

export default class ErrorEvent extends Event 
  constructor(client:CustomClient )
    super(client, "error");
  
  run = async(error:string):Promise<void>=> 
    console.log("Discord client error!", error)
  

在上面的代码中,Event 类是,

// file: src\libs\structure\event\Event.ts
import CustomClient from "../../customClient";

export default class Event  
  client:CustomClient;
  name:string;
  constructor(client:CustomClient, name:string) 
    this.client = client;
    this.name = name;
  

  // a run method that has 1 parameter, error which is a string containing the error message

事件类构造函数有两个参数,客户端和事件名称。每个事件的事件名称都不同。

但我要添加的是一个名为 run 的方法。当事件发生时将调用此运行方法。 run 方法应该在每个子类中定义,而不是在主类中。但是,不同类型的运行方法参数会有所不同。例如,

MessageEvent -> 参数 = message:Message (Discord.Message) ErrorEvent -> Params = error:string(表示错误的字符串) 等等

我不知道如何制作一个允许不同函数使用不同参数的方法。我也想把一个接口和这个类联系起来。

我制作的接口文件,但链接时出错,

// file: src\interface\EventInt.ts
import CustomClient from "../libs/customClient";

export default interface Events 
  client: CustomClient,
  name: string,
  run:(args:unknown) => void
```

【问题讨论】:

【参考方案1】:

如果子类的接口扩展了基类的接口会怎样。比如:

interface Events 
    client: number,
    name: string,

// T will be the type for the run method
interface EventType<T> extends Events 
    run:(args: T) => void // You could use any but of course ...

这样,您的基类可以实现事件,所有子类都可以实现和扩展事件。

export class Event implements Events 
    client: number;
    name:string;
    constructor(client:number, name:string) 
       this.client = client;
       this.name = name;
    

class ErrorEvent extends Event implements EventType<string> 
    client = 4;
    name = "hello";
    run = async(error: string): Promise<void> => 
       console.log("Discord client error!", error)
        

如果你想传递多个参数,你可以像这样使用上下文对象:

run = async(error, anotherError: error: string, anotherError: string[]) 

【讨论】:

这个解决方案感觉不错。但这是它产生的错误。此错误是在扩展 Event 并实现 EventType 的类 ErrorEvent 中产生的。 Property 'run' in type 'ErrorEvent' is not assignable to the same property in base type 'EventType'. Type '(error: string) =&gt; Promise&lt;void&gt;' is not assignable to type '(args: unknown) =&gt; void'. Types of parameters 'error' and 'args' are incompatible. Type 'unknown' is not assignable to type 'string' 哦,我明白了。没错,unknown 可以是任何类型。您可以将 args 键入为 any,但如果您真的不想使用 any,请改用通用接口。我会更新答案。 感谢更新的答案。我会尽快试用。

以上是关于在打字稿中的类中创建具有未知参数的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在打字稿中创建一个零数组?

根据打字稿中的请求参数设置猫鼬的查询过滤器

打字稿中的全局类型

如何将方法的泛型类型限制为打字稿中的对象?

打字稿中具有联合类型键的松散类型对象

打字稿中具有通用键的对象