打字稿类型 A 不可分配给类型 A(相同类型)

Typescript type A is not assignable to type A (same type)

我遇到一个问题,Typescript 告诉我类型 A 不可分配给类型 A,但它们完全相同:

这是一个link to the playground:

declare interface ButtonInteraction {
  user: any;
  customId: string;
  reply: (message: string) => void
}

enum TranslatorLangs {
  FR = 'fr',
  EN = 'en',
}

export class UserService {
  public async setUserLocale(user: any, locale: TranslatorLangs): Promise<any> {
    user.locale = locale;
  }
}

export interface ButtonHandlerInterface {
  commandName: string;
  handle<T = unknown>(interaction: ButtonInteraction, value: T): void | Promise<void>
}

export default class MbtiCommandHandler implements ButtonHandlerInterface {
  public commandName = 'setLocale';

  private userService: UserService = new UserService();

  async handle<TranslatorLangs>(interaction: ButtonInteraction, value: TranslatorLangs): Promise<void> {
    this.userService.setUserLocale(interaction.user, value);
    //                                               ^^^^^
    //                         Argument of type 'TranslatorLangs' is not assignable to parameter of type 'TranslatorLangs'
    interaction.reply(`Ok, so it will be ${interaction.customId}`);

    return interaction.reply('ok');
  }
}

它们实际上不是同一个东西,“TranslatorLangs”这个名字被用来表示两个不同的东西。首先,它是一个枚举。其次,它是 handle 接受的通用参数的名称。要重命名它以便我可以分别引用它们,让我们将句柄函数更改为:

async handle<T>(interaction: ButtonInteraction, value: T): Promise<void>

这一行是说 handle 是一个泛型函数。 “T”是他们决定调用它的任何类型的占位符。他们可能会决定 T 是 TranslatorLangs,但他们也可以传入任何其他内容,例如布尔值。因此,当您尝试将该布尔值传递给 setUserLocale 时,会出现错误。

我认为您要做的是使 ButtonHandlerInterface 本身成为通用的,如:

export interface ButtonHandlerInterface<T = unknown> {
  commandName: string;
  handle(interaction: ButtonInteraction, value: T): void | Promise<void>
}

然后您将像这样使用它:

export default class MbtiCommandHandler implements ButtonHandlerInterface<TranslatorLangs> {
   // ...
  async handle(interaction: ButtonInteraction, value: TranslatorLangs): Promise<void> {
  // ...

Playground link