Skip to content

Add Generic Interaction types #1507

@lisekilis

Description

@lisekilis

Feature

Generic Interaction types that would allow the casting of interaction types based on known data of the command that produced the interaction
This would significantly improve type safety and remove pointless checks in the handling of incoming discord interactions

Ideal solution or implementation

An ideal solution would be the addition of generic types like
GenericAPIInteraction<T>
GenericAPIChatInputApplicationCommandInteraction<T>,
or somehting of this sorts

Specific implementation doesn't matter as long as there is a way to create Interaction types from known command data

Alternative solutions or implementations

No response

Other context

Example of code that would benefit this change:
(this is not exact code but just something to paint the idea)

const exampleCommandData = {
	data: {
		name: 'config',
		description: 'Configure the app settings',
		type: ApplicationCommandType.ChatInput,
		options: [
			{
				name: 'mod role',
				type: ApplicationCommandOptionType.Role,
				description: 'Set the mod role',
			},
		],
	},
};

const executeExample = (interaction: APIChatInputApplicationCommandInteraction) => {
	// interaction here would be a generic that would take the type of commandData passed in instead of being a APIChatInputApplicationCommandInteraction
	const name = interaction.data.name; // "config" instead of string

	const modRole = interaction.data.options?.find((opt) => opt.name === 'mod role'); //
	// options wouldn't be a possibly null generic array but rather an array of the specific options passed in
	if (!modRole || modRole.type !== ApplicationCommandOptionType.Role) {
		return messageResponse('Please provide a valid role', MessageFlags.Ephemeral);
	}
	modRole.value; // role ID instead of string

	// some code to set mod role

	return messageResponse(`Config command executed: ${name}`, MessageFlags.Ephemeral);
};

type InvokedInteractionData = typeof exampleCommandData;

type ExampleCommandInteraction = GenericAPIChatInputApplicationCommandInteraction<InvokedInteractionData>;

const executeExampleWithGenericInteractions = (interaction: ExampleCommandInteraction) => {
	const name = interaction.data.name; // this is just "config"

	const modRole = interaction.data.options.find((opt) => opt.name === 'mod role'); //
	// options wouldn't be a possibly null generic array but rather an array of the specific options passed in
	
	// if (!modRole || modRole.type !== ApplicationCommandOptionType.Role) {
	// 	return messageResponse('Please provide a valid role', MessageFlags.Ephemeral);
	// } // This check is not needed as the type system already knows the type of modRole

	modRole.value; // now correctly typed as role ID instead of string

	// some code to set mod role

	return messageResponse(`Config command executed: ${name}`, MessageFlags.Ephemeral);
};

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions