When attempting to dynamically infer method parameters, I encounter an issue where an implicit 'any' type is inferred, even though a valid method definition is visible when hovering over the execute method. Renaming either method resolves the problem, but I prefer to keep them as they are. How can I achieve this?
type CommandBase<T extends BaseCommandInteraction> = ApplicationCommandData & {
execute(interaction: T): unknown | Promise<unknown>
}
export type ContextMenuCommand = CommandBase<ContextMenuInteraction<"cached">> &
(UserApplicationCommandData | MessageApplicationCommandData)
export type SlashCommand = CommandBase<CommandInteraction<"cached">> &
ChatInputApplicationCommandData
type ExtraLegacyCommandData<TArgs> = {
resolveArgs(args: Args, message: Message): TArgs
}
type LegacyCommand<TArgs> = {
type: "LEGACY"
name: string
description: string
execute(message: Message, args: TArgs): unknown | Promise<unknown>
// eslint-disable-next-line @typescript-eslint/ban-types
} & (TArgs extends void ? {} : ExtraLegacyCommandData<TArgs>)
export type Command<TArgs> =
| ContextMenuCommand
| SlashCommand
| LegacyCommand<TArgs>
export function createCommand<TArgs = void>(command: Command<TArgs>) {
return command
}
export default createCommand({
type: "LEGACY",
name: "",
description: "",
execute(message) {
// Type signature shows `execute(message: Message<boolean>, args: void): unknown`
// But `Parameter 'message' implicitly has an 'any' type.`
},
})
Edit: Inference works when defining both expected function parameters. Avoiding this step with added complexity:
type LegacyCommand<TArgs> = {
type: "LEGACY"
name: string
description: string
execute(
message: Message,
...args: TArgs extends void ? [] : [TArgs]
): unknown | Promise<unknown>
// eslint-disable-next-line @typescript-eslint/ban-types
} & (TArgs extends void ? {} : ExtraLegacyCommandData<TArgs>)
However, an alternative approach also fails:
// (method) execute(message: Message<boolean>): unknown
async execute(message) { // Parameter 'message' implicitly has an 'any' type.