I'm having an issue where Typescript tells me that type A is not assignable to type A, but they're exactly the same:
Here is 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');
}
}
CodePudding user response:
They're not actually the same thing, the name "TranslatorLangs" is being used to mean two different things. First, it's an enum. Second, it's a name for the generic parameter than handle accepts. To rename it so i can refer to them separately, let's change the handle function to:
async handle<T>(interaction: ButtonInteraction, value: T): Promise<void>
This line is saying that handle
is a generic function. "T" is a placeholder for whatever type they decide to call it with. They might decide that T is TranslatorLangs, but they could also pass in anything else, such as a boolean. So when you try to pass that boolean into setUserLocale, you get an error.
I think what you're trying to do is make ButtonHandlerInterface
itself be generic, as in:
export interface ButtonHandlerInterface<T = unknown> {
commandName: string;
handle(interaction: ButtonInteraction, value: T): void | Promise<void>
}
You'll then use it like this:
export default class MbtiCommandHandler implements ButtonHandlerInterface<TranslatorLangs> {
// ...
async handle(interaction: ButtonInteraction, value: TranslatorLangs): Promise<void> {
// ...