Repository: hikari-py/hikari
Pull request #1509 (2023-02-10 22:26:31)

Add type property to component builders
### Summary
<!-- Small summary of the merge request -->

### Checklist
<!-- Make sure to tick all the following boxes by putting an `x` in between (like this `[x]`) -->
- [ ] I have run `nox` and all the pipelines have passed.
- [ ] I have made unittests according to the code I have added/modified/deleted.

### Related issues
<!--
To mention an issue use `#issue-id` and to mention a merge request use `!merge-request-id`
To close/fix an issue use `Close #issue-id` or `Fix #issue-id` (depending on the merge request)
-->



Patch:
diff --git a/changes/1509.breaking.md b/changes/1509.breaking.md
new file mode 100644
index 00000000..5ecc767b
--- /dev/null
+++ b/changes/1509.breaking.md
@@ -0,0 +1,2 @@
+`type` can no-longer be specified while initialise `hikari.impl.special_endpoints.TextSelectMenuBuilder` and `hikari.impl.special_endpoints.ChannelSelectMenuBuilder`.
+`hikari.api.special_endpoints.SelectOptionBuilder` no-longer inherits from `hikari.api.special_endpoints.ComponentBuilder` (but it still has a `build` method).
diff --git a/changes/1509.feature.md b/changes/1509.feature.md
new file mode 100644
index 00000000..75ccc05e
--- /dev/null
+++ b/changes/1509.feature.md
@@ -0,0 +1,1 @@
+`type` property to the component builders.
diff --git a/hikari/api/event_manager.py b/hikari/api/event_manager.py
index 189d3aa8..84012902 100644
--- a/hikari/api/event_manager.py
+++ b/hikari/api/event_manager.py
@@ -35,6 +35,8 @@
 if typing.TYPE_CHECKING:
     import types
 
+    from typing_extensions import Self
+
     from hikari.api import shard as gateway_shard
     from hikari.internal import data_binding
 
@@ -44,8 +46,6 @@
         [gateway_shard.GatewayShard, data_binding.JSONObject], typing.Coroutine[typing.Any, typing.Any, None]
     ]
 
-    _EventStreamT = typing.TypeVar("_EventStreamT")
-
 
 class EventStream(iterators.LazyIterator[base_events.EventT], abc.ABC):
     """A base abstract class for all event streamers.
@@ -110,10 +110,10 @@ def open(self) -> None:
 
     @abc.abstractmethod
     def filter(
-        self: _EventStreamT,
+        self,
         *predicates: typing.Union[typing.Tuple[str, typing.Any], typing.Callable[[base_events.EventT], bool]],
         **attrs: typing.Any,
-    ) -> _EventStreamT:
+    ) -> Self:
         """Filter the items by one or more conditions.
 
         Each condition is treated as a predicate, being called with each item
@@ -144,7 +144,7 @@ def filter(
         """
 
     @abc.abstractmethod
-    def __enter__(self: _EventStreamT) -> _EventStreamT:
+    def __enter__(self) -> Self:
         raise NotImplementedError
 
     @abc.abstractmethod
diff --git a/hikari/api/special_endpoints.py b/hikari/api/special_endpoints.py
index d86b038c..77bf6d3d 100644
--- a/hikari/api/special_endpoints.py
+++ b/hikari/api/special_endpoints.py
@@ -55,6 +55,8 @@
 if typing.TYPE_CHECKING:
     import types
 
+    from typing_extensions import Self
+
     from hikari import channels
     from hikari import colors
     from hikari import commands
@@ -74,8 +76,6 @@
     from hikari.interactions import base_interactions
     from hikari.internal import time
 
-    _T = typing.TypeVar("_T")
-
 _SelectMenuBuilderT = typing.TypeVar("_SelectMenuBuilderT", bound="SelectMenuBuilder[typing.Any]")
 _ContainerT = typing.TypeVar("_ContainerT")
 
@@ -564,7 +564,7 @@ def flags(self) -> typing.Union[undefined.UndefinedType, int, messages.MessageFl
         """
 
     @abc.abstractmethod
-    def set_flags(self: _T, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /) -> _T:
+    def set_flags(self, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /) -> Self:
         """Set message flags for this response.
 
         .. note::
@@ -593,7 +593,7 @@ def choices(self) -> typing.Sequence[commands.CommandChoice]:
         """Autocomplete choices."""
 
     @abc.abstractmethod
-    def set_choices(self: _T, choices: typing.Sequence[commands.CommandChoice], /) -> _T:
+    def set_choices(self, choices: typing.Sequence[commands.CommandChoice], /) -> Self:
         """Set autocomplete choices.
 
         Returns
@@ -689,7 +689,7 @@ def user_mentions(
         """
 
     @abc.abstractmethod
-    def clear_attachments(self: _T, /) -> _T:
+    def clear_attachments(self, /) -> Self:
         """Clear attachments for this response.
 
         This is only useful for message update responses, where you might want to
@@ -702,7 +702,7 @@ def clear_attachments(self: _T, /) -> _T:
         """
 
     @abc.abstractmethod
-    def add_attachment(self: _T, attachment: files.Resourceish, /) -> _T:
+    def add_attachment(self, attachment: files.Resourceish, /) -> Self:
         """Add an attachment to this response.
 
         Parameters
@@ -717,7 +717,7 @@ def add_attachment(self: _T, attachment: files.Resourceish, /) -> _T:
         """
 
     @abc.abstractmethod
-    def add_component(self: _T, component: ComponentBuilder, /) -> _T:
+    def add_component(self, component: ComponentBuilder, /) -> Self:
         """Add a component to this response.
 
         Parameters
@@ -732,7 +732,7 @@ def add_component(self: _T, component: ComponentBuilder, /) -> _T:
         """
 
     @abc.abstractmethod
-    def add_embed(self: _T, embed: embeds_.Embed, /) -> _T:
+    def add_embed(self, embed: embeds_.Embed, /) -> Self:
         """Add an embed to this response.
 
         Parameters
@@ -747,7 +747,7 @@ def add_embed(self: _T, embed: embeds_.Embed, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_content(self: _T, content: undefined.UndefinedOr[str], /) -> _T:
+    def set_content(self, content: undefined.UndefinedOr[str], /) -> Self:
         """Set the response's message content.
 
         Parameters
@@ -762,7 +762,7 @@ def set_content(self: _T, content: undefined.UndefinedOr[str], /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_flags(self: _T, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /) -> _T:
+    def set_flags(self, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /) -> Self:
         """Set message flags for this response.
 
         .. note::
@@ -781,7 +781,7 @@ def set_flags(self: _T, flags: typing.Union[undefined.UndefinedType, int, messag
         """
 
     @abc.abstractmethod
-    def set_tts(self: _T, tts: undefined.UndefinedOr[bool], /) -> _T:
+    def set_tts(self, tts: undefined.UndefinedOr[bool], /) -> Self:
         """Set whether this response should trigger text-to-speech processing.
 
         Parameters
@@ -796,7 +796,7 @@ def set_tts(self: _T, tts: undefined.UndefinedOr[bool], /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_mentions_everyone(self: _T, mentions: undefined.UndefinedOr[bool] = undefined.UNDEFINED, /) -> _T:
+    def set_mentions_everyone(self, mentions: undefined.UndefinedOr[bool] = undefined.UNDEFINED, /) -> Self:
         """Set whether this response should be able to mention @everyone/@here.
 
         Parameters
@@ -812,12 +812,12 @@ def set_mentions_everyone(self: _T, mentions: undefined.UndefinedOr[bool] = unde
 
     @abc.abstractmethod
     def set_role_mentions(
-        self: _T,
+        self,
         mentions: undefined.UndefinedOr[
             typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool]
         ] = undefined.UNDEFINED,
         /,
-    ) -> _T:
+    ) -> Self:
         """Set whether and what role mentions should be possible for this response.
 
         Parameters
@@ -835,12 +835,12 @@ def set_role_mentions(
 
     @abc.abstractmethod
     def set_user_mentions(
-        self: _T,
+        self,
         mentions: undefined.UndefinedOr[
             typing.Union[snowflakes.SnowflakeishSequence[users.PartialUser], bool]
         ] = undefined.UNDEFINED,
         /,
-    ) -> _T:
+    ) -> Self:
         """Set whether and what user mentions should be possible for this response.
 
         Parameters
@@ -888,7 +888,7 @@ def components(self) -> undefined.UndefinedOr[typing.Sequence[ComponentBuilder]]
         """Sequence of component builders to send in this modal."""
 
     @abc.abstractmethod
-    def set_title(self: _T, title: str, /) -> _T:
+    def set_title(self, title: str, /) -> Self:
         """Set the title that will show up in the modal.
 
         Parameters
@@ -898,7 +898,7 @@ def set_title(self: _T, title: str, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_custom_id(self: _T, custom_id: str, /) -> _T:
+    def set_custom_id(self, custom_id: str, /) -> Self:
         """Set the developer set custom ID used for identifying interactions with this modal.
 
         Parameters
@@ -908,7 +908,7 @@ def set_custom_id(self: _T, custom_id: str, /) -> _T:
         """
 
     @abc.abstractmethod
-    def add_component(self: _T, component: ComponentBuilder, /) -> _T:
+    def add_component(self, component: ComponentBuilder, /) -> Self:
         """Add a component to this modal.
 
         Parameters
@@ -971,7 +971,7 @@ def name_localizations(self) -> typing.Mapping[typing.Union[locales.Locale, str]
         """Name localizations set for this command."""
 
     @abc.abstractmethod
-    def set_id(self: _T, id_: undefined.UndefinedOr[snowflakes.Snowflakeish], /) -> _T:
+    def set_id(self, id_: undefined.UndefinedOr[snowflakes.Snowflakeish], /) -> Self:
         """Set the ID of this command.
 
         Parameters
@@ -987,8 +987,8 @@ def set_id(self: _T, id_: undefined.UndefinedOr[snowflakes.Snowflakeish], /) ->
 
     @abc.abstractmethod
     def set_default_member_permissions(
-        self: _T, default_member_permissions: typing.Union[undefined.UndefinedType, int, permissions_.Permissions], /
-    ) -> _T:
+        self, default_member_permissions: typing.Union[undefined.UndefinedType, int, permissions_.Permissions], /
+    ) -> Self:
         """Set the member permissions necessary to utilize this command by default.
 
         Parameters
@@ -1006,7 +1006,7 @@ def set_default_member_permissions(
         """
 
     @abc.abstractmethod
-    def set_is_dm_enabled(self: _T, state: undefined.UndefinedOr[bool], /) -> _T:
+    def set_is_dm_enabled(self, state: undefined.UndefinedOr[bool], /) -> Self:
         """Set whether this command will be enabled in DMs with the bot.
 
         Parameters
@@ -1021,7 +1021,7 @@ def set_is_dm_enabled(self: _T, state: undefined.UndefinedOr[bool], /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_is_nsfw(self: _T, state: undefined.UndefinedOr[bool], /) -> _T:
+    def set_is_nsfw(self, state: undefined.UndefinedOr[bool], /) -> Self:
         """Set whether this command will be age-restricted.
 
         Parameters
@@ -1037,8 +1037,8 @@ def set_is_nsfw(self: _T, state: undefined.UndefinedOr[bool], /) -> _T:
 
     @abc.abstractmethod
     def set_name_localizations(
-        self: _T, name_localizations: typing.Mapping[typing.Union[locales.Locale, str], str], /
-    ) -> _T:
+        self, name_localizations: typing.Mapping[typing.Union[locales.Locale, str], str], /
+    ) -> Self:
         """Set the name localizations for this command.
 
         Parameters
@@ -1122,10 +1122,10 @@ def description_localizations(
 
     @abc.abstractmethod
     def set_description_localizations(
-        self: _T,
+        self,
         description_localizations: typing.Mapping[typing.Union[locales.Locale, str], str],
         /,
-    ) -> _T:
+    ) -> Self:
         """Set the localised descriptions for this command.
 
         Parameters
@@ -1145,7 +1145,7 @@ def options(self) -> typing.Sequence[commands.CommandOption]:
         """Sequence of up to 25 of the options set for this command."""
 
     @abc.abstractmethod
-    def add_option(self: _T, option: commands.CommandOption) -> _T:
+    def add_option(self, option: commands.CommandOption) -> Self:
         """Add an option to this command.
 
         .. note::
@@ -1243,6 +1243,11 @@ class ComponentBuilder(abc.ABC):
 
     __slots__: typing.Sequence[str] = ()
 
+    @property
+    @abc.abstractmethod
+    def type(self) -> typing.Union[int, components_.ComponentType]:
+        """Type of component this builder represents."""
+
     @abc.abstractmethod
     def build(self) -> typing.MutableMapping[str, typing.Any]:
         """Build a JSON object from this builder.
@@ -1259,6 +1264,11 @@ class ButtonBuilder(ComponentBuilder, abc.ABC, typing.Generic[_ContainerT]):
 
     __slots__: typing.Sequence[str] = ()
 
+    @property
+    @abc.abstractmethod
+    def type(self) -> typing.Literal[components_.ComponentType.BUTTON]:
+        """Type of component this builder represents."""
+
     @property
     @abc.abstractmethod
     def style(self) -> typing.Union[components_.ButtonStyle, int]:
@@ -1286,8 +1296,8 @@ def is_disabled(self) -> bool:
 
     @abc.abstractmethod
     def set_emoji(
-        self: _T, emoji: typing.Union[snowflakes.Snowflakeish, emojis.Emoji, str, undefined.UndefinedType], /
-    ) -> _T:
+        self, emoji: typing.Union[snowflakes.Snowflakeish, emojis.Emoji, str, undefined.UndefinedType], /
+    ) -> Self:
         """Set the emoji to display on this button.
 
         Parameters
@@ -1303,7 +1313,7 @@ def set_emoji(
         """
 
     @abc.abstractmethod
-    def set_label(self: _T, label: undefined.UndefinedOr[str], /) -> _T:
+    def set_label(self, label: undefined.UndefinedOr[str], /) -> Self:
         """Set the text label which should be displayed on this button.
 
         Parameters
@@ -1320,7 +1330,7 @@ def set_label(self: _T, label: undefined.UndefinedOr[str], /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_is_disabled(self: _T, state: bool, /) -> _T:
+    def set_is_disabled(self, state: bool, /) -> Self:
         """Set whether this button should be disabled.
 
         Parameters
@@ -1369,7 +1379,7 @@ def custom_id(self) -> str:
         """Developer set custom ID used for identifying interactions with this button."""
 
 
-class SelectOptionBuilder(ComponentBuilder, abc.ABC, typing.Generic[_SelectMenuBuilderT]):
+class SelectOptionBuilder(abc.ABC, typing.Generic[_SelectMenuBuilderT]):
     """Builder class for select menu options."""
 
     __slots__: typing.Sequence[str] = ()
@@ -1400,7 +1410,7 @@ def is_default(self) -> bool:
         """Whether this option should be marked as selected by default."""
 
     @abc.abstractmethod
-    def set_description(self: _T, value: undefined.UndefinedOr[str], /) -> _T:
+    def set_description(self, value: undefined.UndefinedOr[str], /) -> Self:
         """Set the option's description.
 
         Parameters
@@ -1417,8 +1427,8 @@ def set_description(self: _T, value: undefined.UndefinedOr[str], /) -> _T:
 
     @abc.abstractmethod
     def set_emoji(
-        self: _T, emoji: typing.Union[snowflakes.Snowflakeish, emojis.Emoji, str, undefined.UndefinedType], /
-    ) -> _T:
+        self, emoji: typing.Union[snowflakes.Snowflakeish, emojis.Emoji, str, undefined.UndefinedType], /
+    ) -> Self:
         """Set the emoji to display on this option.
 
         Parameters
@@ -1434,7 +1444,7 @@ def set_emoji(
         """
 
     @abc.abstractmethod
-    def set_is_default(self: _T, state: bool, /) -> _T:
+    def set_is_default(self, state: bool, /) -> Self:
         """Set whether this option should be selected by default.
 
         Parameters
@@ -1460,6 +1470,16 @@ def add_to_menu(self) -> _SelectMenuBuilderT:
             The menu component that owns this button.
         """
 
+    @abc.abstractmethod
+    def build(self) -> typing.MutableMapping[str, typing.Any]:
+        """Build a JSON object from this builder.
+
+        Returns
+        -------
+        typing.MutableMapping[str, typing.Any]
+            The built json object representation of this builder.
+        """
+
 
 class SelectMenuBuilder(ComponentBuilder, abc.ABC, typing.Generic[_ContainerT]):
     """Builder class for a select menu."""
@@ -1502,7 +1522,7 @@ def max_values(self) -> int:
         """
 
     @abc.abstractmethod
-    def set_is_disabled(self: _T, state: bool, /) -> _T:
+    def set_is_disabled(self, state: bool, /) -> Self:
         """Set whether this option is disabled.
 
         Defaults to `False`.
@@ -1519,7 +1539,7 @@ def set_is_disabled(self: _T, state: bool, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_placeholder(self: _T, value: undefined.UndefinedOr[str], /) -> _T:
+    def set_placeholder(self, value: undefined.UndefinedOr[str], /) -> Self:
         """Set place-holder text to be shown when no option is selected.
 
         Parameters
@@ -1535,7 +1555,7 @@ def set_placeholder(self: _T, value: undefined.UndefinedOr[str], /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_min_values(self: _T, value: int, /) -> _T:
+    def set_min_values(self, value: int, /) -> Self:
         """Set the minimum amount of options which need to be selected for this menu.
 
         .. note::
@@ -1554,7 +1574,7 @@ def set_min_values(self: _T, value: int, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_max_values(self: _T, value: int, /) -> _T:
+    def set_max_values(self, value: int, /) -> Self:
         """Set the maximum amount of options which can be selected for this menu.
 
         .. note::
@@ -1590,11 +1610,11 @@ class TextSelectMenuBuilder(SelectMenuBuilder[_ContainerT], abc.ABC, typing.Gene
 
     @property
     @abc.abstractmethod
-    def options(self: _SelectMenuBuilderT) -> typing.Sequence[SelectOptionBuilder[_SelectMenuBuilderT]]:
+    def options(self) -> typing.Sequence[SelectOptionBuilder[Self]]:
         """Sequence of the options set for this select menu."""
 
     @abc.abstractmethod
-    def add_option(self: _SelectMenuBuilderT, label: str, value: str, /) -> SelectOptionBuilder[_SelectMenuBuilderT]:
+    def add_option(self, label: str, value: str, /) -> SelectOptionBuilder[Self]:
         """Add an option to this menu.
 
         .. note::
@@ -1626,7 +1646,7 @@ def channel_types(self) -> typing.Sequence[channels.ChannelType]:
         """The channel types that can be selected in this menu."""
 
     @abc.abstractmethod
-    def set_channel_types(self: _T, value: typing.Sequence[channels.ChannelType], /) -> _T:
+    def set_channel_types(self, value: typing.Sequence[channels.ChannelType], /) -> Self:
         """Set the valid channel types for this menu.
 
         Parameters
@@ -1646,6 +1666,11 @@ class TextInputBuilder(ComponentBuilder, abc.ABC, typing.Generic[_ContainerT]):
 
     __slots__: typing.Sequence[str] = ()
 
+    @property
+    @abc.abstractmethod
+    def type(self) -> typing.Literal[components_.ComponentType.TEXT_INPUT]:
+        """Type of component this builder represents."""
+
     @property
     @abc.abstractmethod
     def custom_id(self) -> str:
@@ -1692,7 +1717,7 @@ def max_length(self) -> undefined.UndefinedOr[int]:
         """Maximum length the text should have."""
 
     @abc.abstractmethod
-    def set_style(self: _T, style: typing.Union[components_.TextInputStyle, int], /) -> _T:
+    def set_style(self, style: typing.Union[components_.TextInputStyle, int], /) -> Self:
         """Set the style to use for the text input.
 
         Parameters
@@ -1707,7 +1732,7 @@ def set_style(self: _T, style: typing.Union[components_.TextInputStyle, int], /)
         """
 
     @abc.abstractmethod
-    def set_custom_id(self: _T, custom_id: str, /) -> _T:
+    def set_custom_id(self, custom_id: str, /) -> Self:
         """Set the developer set custom ID used for identifying this text input.
 
         Parameters
@@ -1722,7 +1747,7 @@ def set_custom_id(self: _T, custom_id: str, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_label(self: _T, label: str, /) -> _T:
+    def set_label(self, label: str, /) -> Self:
         """Set the label above this text input.
 
         Parameters
@@ -1737,7 +1762,7 @@ def set_label(self: _T, label: str, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_placeholder(self: _T, placeholder: str, /) -> _T:
+    def set_placeholder(self, placeholder: str, /) -> Self:
         """Set the placeholder text for when the text input is empty.
 
         Parameters
@@ -1752,7 +1777,7 @@ def set_placeholder(self: _T, placeholder: str, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_value(self: _T, value: str, /) -> _T:
+    def set_value(self, value: str, /) -> Self:
         """Pre-filled text that will be sent if the user does not write anything.
 
         Parameters
@@ -1767,7 +1792,7 @@ def set_value(self: _T, value: str, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_required(self: _T, required: bool, /) -> _T:
+    def set_required(self, required: bool, /) -> Self:
         """Set whether this text input is required to be filled-in.
 
         Parameters
@@ -1782,7 +1807,7 @@ def set_required(self: _T, required: bool, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_min_length(self: _T, min_length: int, /) -> _T:
+    def set_min_length(self, min_length: int, /) -> Self:
         """Set the minimum length the text should have.
 
         Parameters
@@ -1797,7 +1822,7 @@ def set_min_length(self: _T, min_length: int, /) -> _T:
         """
 
     @abc.abstractmethod
-    def set_max_length(self: _T, max_length: int, /) -> _T:
+    def set_max_length(self, max_length: int, /) -> Self:
         """Set the maximum length the text should have.
 
         Parameters
@@ -1827,17 +1852,18 @@ class MessageActionRowBuilder(ComponentBuilder, abc.ABC):
 
     __slots__: typing.Sequence[str] = ()
 
+    @property
+    @abc.abstractmethod
+    def type(self) -> typing.Literal[components_.ComponentType.ACTION_ROW]:
+        """Type of component this builder represents."""
+
     @property
     @abc.abstractmethod
     def components(self) -> typing.Sequence[ComponentBuilder]:
         """Sequence of the component builders registered within this action row."""
 
     @abc.abstractmethod
-    def add_component(
-        self: _T,
-        component: ComponentBuilder,
-        /,
-    ) -> _T:
+    def add_component(self, component: ComponentBuilder, /) -> Self:
         """Add a component to this action row builder.
 
         .. warning::
@@ -1859,28 +1885,28 @@ def add_component(
     @typing.overload
     @abc.abstractmethod
     def add_button(
-        self: _T, style: components_.InteractiveButtonTypesT, custom_id: str, /
-    ) -> InteractiveButtonBuilder[_T]:
+        self, style: components_.InteractiveButtonTypesT, custom_id: str, /
+    ) -> InteractiveButtonBuilder[Self]:
         ...
 
     @typing.overload
     @abc.abstractmethod
     def add_button(
-        self: _T, style: typing.Literal[components_.ButtonStyle.LINK, 5], url: str, /
-    ) -> LinkButtonBuilder[_T]:
+        self, style: typing.Literal[components_.ButtonStyle.LINK, 5], url: str, /
+    ) -> LinkButtonBuilder[Self]:
         ...
 
     @typing.overload
     @abc.abstractmethod
     def add_button(
-        self: _T, style: typing.Union[int, components_.ButtonStyle], url_or_custom_id: str, /
-    ) -> typing.Union[LinkButtonBuilder[_T], InteractiveButtonBuilder[_T]]:
+        self, style: typing.Union[int, components_.ButtonStyle], url_or_custom_id: str, /
+    ) -> typing.Union[LinkButtonBuilder[Self], InteractiveButtonBuilder[Self]]:
         ...
 
     @abc.abstractmethod
     def add_button(
-        self: _T, style: typing.Union[int, components_.ButtonStyle], url_or_custom_id: str, /
-    ) -> typing.Union[LinkButtonBuilder[_T], InteractiveButtonBuilder[_T]]:
+        self, style: typing.Union[int, components_.ButtonStyle], url_or_custom_id: str, /
+    ) -> typing.Union[LinkButtonBuilder[Self], InteractiveButtonBuilder[Self]]:
         """Add a button component to this action row builder.
 
         Parameters
@@ -1905,51 +1931,51 @@ def add_button(
     @typing.overload  # Deprecated overload
     @abc.abstractmethod
     def add_select_menu(
-        self: _T,
+        self,
         custom_id: str,
         /,
-    ) -> TextSelectMenuBuilder[_T]:
+    ) -> TextSelectMenuBuilder[Self]:
         ...
 
     @typing.overload
     @abc.abstractmethod
     def add_select_menu(
-        self: _T,
+        self,
         type_: typing.Literal[components_.ComponentType.TEXT_SELECT_MENU, 3],
         custom_id: str,
         /,
-    ) -> TextSelectMenuBuilder[_T]:
+    ) -> TextSelectMenuBuilder[Self]:
         ...
 
     @typing.overload
     @abc.abstractmethod
     def add_select_menu(
-        self: _T,
+        self,
         type_: typing.Literal[components_.ComponentType.CHANNEL_SELECT_MENU, 8],
         custom_id: str,
         /,
-    ) -> ChannelSelectMenuBuilder[_T]:
+    ) -> ChannelSelectMenuBuilder[Self]:
         ...
 
     @typing.overload
     @abc.abstractmethod
     def add_select_menu(
-        self: _T,
+        self,
         type_: typing.Union[components_.ComponentType, int],
         custom_id: str,
         /,
-    ) -> SelectMenuBuilder[_T]:
+    ) -> SelectMenuBuilder[Self]:
         ...
 
     @abc.abstractmethod
     def add_select_menu(
-        self: _T,
+        self,
         type_: typing.Union[components_.ComponentType, int, str],
         # These have default during the deprecation period for backwards compatibility, as custom_id
         # used to come first
         custom_id: str = "",
         /,
-    ) -> SelectMenuBuilder[_T]:
+    ) -> SelectMenuBuilder[Self]:
         """Add a select menu component to this action row builder.
 
         .. deprecated:: 2.0.0.dev116
@@ -1982,6 +2008,11 @@ class ModalActionRowBuilder(ComponentBuilder, abc.ABC):
 
     __slots__: typing.Sequence[str] = ()
 
+    @property
+    @abc.abstractmethod
+    def type(self) -> typing.Literal[components_.ComponentType.ACTION_ROW]:
+        """Type of component this builder represents."""
+
     @property
     @abc.abstractmethod
     def components(self) -> typing.Sequence[ComponentBuilder]:
@@ -1989,10 +2020,10 @@ def components(self) -> typing.Sequence[ComponentBuilder]:
 
     @abc.abstractmethod
     def add_component(
-        self: _T,
+        self,
         component: ComponentBuilder,
         /,
-    ) -> _T:
+    ) -> Self:
         """Add a component to this action row builder.
 
         .. warning::
@@ -2013,10 +2044,10 @@ def add_component(
 
     @abc.abstractmethod
     def add_text_input(
-        self: _T,
+        self,
         custom_id: str,
         label: str,
-    ) -> TextInputBuilder[_T]:
+    ) -> TextInputBuilder[Self]:
         """Add a text input component to this action row builder.
 
         Parameters
diff --git a/hikari/api/voice.py b/hikari/api/voice.py
index d158ff59..f8985fb6 100644
--- a/hikari/api/voice.py
+++ b/hikari/api/voice.py
@@ -31,12 +31,12 @@
 from hikari.events import voice_events
 
 if typing.TYPE_CHECKING:
+    from typing_extensions import Self
+
     from hikari import channels
     from hikari import guilds
     from hikari import snowflakes
 
-    _T = typing.TypeVar("_T")
-
     _VoiceConnectionT = typing.TypeVar("_VoiceConnectionT", bound="VoiceConnection")
 
 
@@ -149,18 +149,18 @@ class VoiceConnection(abc.ABC):
     @classmethod
     @abc.abstractmethod
     async def initialize(
-        cls: typing.Type[_T],
+        cls,
         channel_id: snowflakes.Snowflake,
         endpoint: str,
         guild_id: snowflakes.Snowflake,
-        on_close: typing.Callable[[_T], typing.Awaitable[None]],
+        on_close: typing.Callable[[Self], typing.Awaitable[None]],
         owner: VoiceComponent,
         session_id: str,
         shard_id: int,
         token: str,
         user_id: snowflakes.Snowflake,
         **kwargs: typing.Any,
-    ) -> _T:
+    ) -> Self:
         """Initialize and connect the voice connection.
 
         Parameters
diff --git a/hikari/commands.py b/hikari/commands.py
index 3a2cb76c..41c2c3a7 100644
--- a/hikari/commands.py
+++ b/hikari/commands.py
@@ -254,9 +254,9 @@ class PartialCommand(snowflakes.Unique):
     """Auto-incrementing version identifier updated during substantial record changes."""
 
     name_localizations: typing.Mapping[typing.Union[locales.Locale, str], str] = attr.field(
-        eq=False, factory=dict, hash=False, repr=False
+        eq=False, hash=False, repr=False
     )
-    """A mapping of name localizations for this option."""
+    """A mapping of name localizations for this command."""
 
     async def fetch_self(self) -> PartialCommand:
         """Fetch an up-to-date version of this command object.
@@ -447,7 +447,7 @@ class SlashCommand(PartialCommand):
     description_localizations: typing.Mapping[typing.Union[locales.Locale, str], str] = attr.field(
         eq=False, hash=False, repr=False
     )
-    """A set of description localizations for this command"""
+    """A set of description localizations for this command."""
 
     options: typing.Optional[typing.Sequence[CommandOption]] = attr.field(eq=False, hash=False, repr=False)
     """Sequence of up to (and including) 25 of the options for this command."""
diff --git a/hikari/impl/entity_factory.py b/hikari/impl/entity_factory.py
index fb753048..199252e3 100644
--- a/hikari/impl/entity_factory.py
+++ b/hikari/impl/entity_factory.py
@@ -2368,7 +2368,7 @@ def deserialize_partial_interaction(self, payload: data_binding.JSONObject) -> b
     def _deserialize_interaction_command_option(
         self, payload: data_binding.JSONObject
     ) -> command_interactions.CommandInteractionOption:
-        suboptions: typing.Optional[typing.List[command_interactions.CommandInteractionOption]] = None
+        suboptions: typing.Optional[typing.Sequence[command_interactions.CommandInteractionOption]] = None
         if raw_suboptions := payload.get("options"):
             suboptions = [self._deserialize_interaction_command_option(suboption) for suboption in raw_suboptions]
 
@@ -2381,14 +2381,14 @@ def _deserialize_interaction_command_option(
             name=payload["name"],
             type=option_type,
             value=value,
-            options=suboptions,
+            options=suboptions,  # type: ignore[arg-type]  # MyPy gets the type equality wrong here.
         )
 
     def _deserialize_autocomplete_interaction_option(
         self,
         payload: data_binding.JSONObject,
     ) -> command_interactions.AutocompleteInteractionOption:
-        suboptions: typing.Optional[typing.List[command_interactions.AutocompleteInteractionOption]] = None
+        suboptions: typing.Optional[typing.Sequence[command_interactions.AutocompleteInteractionOption]] = None
         if raw_suboptions := payload.get("options"):
             suboptions = [self._deserialize_autocomplete_interaction_option(suboption) for suboption in raw_suboptions]
 
@@ -2403,7 +2403,7 @@ def _deserialize_autocomplete_interaction_option(
             name=payload["name"],
             type=option_type,
             value=value,
-            options=suboptions,
+            options=suboptions,  # type: ignore[arg-type]  # MyPy gets the type equality wrong here.
             is_focused=is_focused,
         )
 
diff --git a/hikari/impl/event_manager_base.py b/hikari/impl/event_manager_base.py
index 12cf8d42..9e7f3e24 100644
--- a/hikari/impl/event_manager_base.py
+++ b/hikari/impl/event_manager_base.py
@@ -50,6 +50,8 @@
 from hikari.internal import ux
 
 if typing.TYPE_CHECKING:
+    from typing_extensions import Self
+
     from hikari import intents as intents_
     from hikari.api import event_factory as event_factory_
     from hikari.api import shard as gateway_shard
@@ -73,8 +75,6 @@
         typing.Coroutine[typing.Any, typing.Any, None],
     ]
 
-    _EventStreamT = typing.TypeVar("_EventStreamT", bound="EventStream[typing.Any]")
-
 
 if sys.version_info >= (3, 10):
     # We can use types.UnionType on 3.10+
@@ -162,7 +162,7 @@ def __init__(
         # The registered wrapping function for the weak ref to this class's _listener method.
         self._timeout = timeout
 
-    def __enter__(self: _EventStreamT) -> _EventStreamT:
+    def __enter__(self) -> Self:
         self.open()
         return self
 
@@ -229,10 +229,10 @@ def close(self) -> None:
         self._active = False
 
     def filter(
-        self: _EventStreamT,
+        self,
         *predicates: typing.Union[typing.Tuple[str, typing.Any], typing.Callable[[base_events.EventT], bool]],
         **attrs: typing.Any,
-    ) -> _EventStreamT:
+    ) -> Self:
         filter_ = self._map_predicates_and_attr_getters("filter", *predicates, **attrs)
         if self._active:
             self._queue = [entry for entry in self._queue if filter_(entry)]
diff --git a/hikari/impl/special_endpoints.py b/hikari/impl/special_endpoints.py
index fa8543af..92974d74 100644
--- a/hikari/impl/special_endpoints.py
+++ b/hikari/impl/special_endpoints.py
@@ -75,6 +75,8 @@
     import concurrent.futures
     import types
 
+    from typing_extensions import Self
+
     from hikari import applications
     from hikari import audit_logs
     from hikari import colors
@@ -88,24 +90,7 @@
     from hikari.api import rest as rest_api
 
     _T = typing.TypeVar("_T")
-    _CommandBuilderT = typing.TypeVar("_CommandBuilderT", bound="CommandBuilder")
-    _SlashCommandBuilderT = typing.TypeVar("_SlashCommandBuilderT", bound="SlashCommandBuilder")
-    _InteractionMessageBuilderT = typing.TypeVar("_InteractionMessageBuilderT", bound="InteractionMessageBuilder")
-    _InteractionDeferredBuilderT = typing.TypeVar("_InteractionDeferredBuilderT", bound="InteractionDeferredBuilder")
-    _InteractionAutocompleteBuilderT = typing.TypeVar(
-        "_InteractionAutocompleteBuilderT", bound="InteractionAutocompleteBuilder"
-    )
-    _InteractionModalBuilderT = typing.TypeVar("_InteractionModalBuilderT", bound="InteractionModalBuilder")
-    _MessageActionRowBuilderT = typing.TypeVar("_MessageActionRowBuilderT", bound="MessageActionRowBuilder")
-    _ModalActionRowBuilderT = typing.TypeVar("_ModalActionRowBuilderT", bound="ModalActionRowBuilder")
-    _ButtonBuilderT = typing.TypeVar("_ButtonBuilderT", bound="_ButtonBuilder[typing.Any]")
-    _SelectOptionBuilderT = typing.TypeVar("_SelectOptionBuilderT", bound="_SelectOptionBuilder[typing.Any]")
-    _SelectMenuBuilderT = typing.TypeVar("_SelectMenuBuilderT", bound="SelectMenuBuilder[typing.Any]")
     _TextSelectMenuBuilderT = typing.TypeVar("_TextSelectMenuBuilderT", bound="TextSelectMenuBuilder[typing.Any]")
-    _ChannelSelectMenuBuilderT = typing.TypeVar(
-        "_ChannelSelectMenuBuilderT", bound="ChannelSelectMenuBuilder[typing.Any]"
-    )
-    _TextInputBuilderT = typing.TypeVar("_TextInputBuilderT", bound="TextInputBuilder[typing.Any]")
 
     class _RequestCallSig(typing.Protocol):
         async def __call__(
@@ -133,7 +118,7 @@ def __call__(
 
     # Hack around used to avoid recursive generic types leading to type checker issues in builders
     class _ContainerProto(typing.Protocol):
-        def add_component(self: _T, component: special_endpoints.ComponentBuilder, /) -> _T:
+        def add_component(self, component: special_endpoints.ComponentBuilder, /) -> Self:
             raise NotImplementedError
 
 
@@ -924,9 +909,7 @@ def type(self) -> typing.Literal[base_interactions.ResponseType.AUTOCOMPLETE]:
     def choices(self) -> typing.Sequence[commands.CommandChoice]:
         return self._choices
 
-    def set_choices(
-        self: _InteractionAutocompleteBuilderT, choices: typing.Sequence[commands.CommandChoice], /
-    ) -> _InteractionAutocompleteBuilderT:
+    def set_choices(self, choices: typing.Sequence[commands.CommandChoice], /) -> Self:
         """Set autocomplete choices.
 
         Returns
@@ -974,9 +957,7 @@ def type(self) -> base_interactions.DeferredResponseTypesT:
     def flags(self) -> typing.Union[undefined.UndefinedType, int, messages.MessageFlag]:
         return self._flags
 
-    def set_flags(
-        self: _InteractionDeferredBuilderT, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /
-    ) -> _InteractionDeferredBuilderT:
+    def set_flags(self, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /) -> Self:
         self._flags = flags
         return self
 
@@ -1084,74 +1065,64 @@ def user_mentions(
     ) -> undefined.UndefinedOr[typing.Union[snowflakes.SnowflakeishSequence[users.PartialUser], bool]]:
         return self._user_mentions
 
-    def clear_attachments(self: _InteractionMessageBuilderT, /) -> _InteractionMessageBuilderT:
+    def clear_attachments(self, /) -> Self:
         self._attachments = None
         return self
 
-    def add_attachment(
-        self: _InteractionMessageBuilderT, attachment: files.Resourceish, /
-    ) -> _InteractionMessageBuilderT:
+    def add_attachment(self, attachment: files.Resourceish, /) -> Self:
         if not self._attachments:
             self._attachments = []
 
         self._attachments.append(attachment)
         return self
 
-    def add_component(
-        self: _InteractionMessageBuilderT, component: special_endpoints.ComponentBuilder, /
-    ) -> _InteractionMessageBuilderT:
+    def add_component(self, component: special_endpoints.ComponentBuilder, /) -> Self:
         if self._components is undefined.UNDEFINED:
             self._components = []
 
         self._components.append(component)
         return self
 
-    def add_embed(self: _InteractionMessageBuilderT, embed: embeds_.Embed, /) -> _InteractionMessageBuilderT:
+    def add_embed(self, embed: embeds_.Embed, /) -> Self:
         if self._embeds is undefined.UNDEFINED:
             self._embeds = []
 
         self._embeds.append(embed)
         return self
 
-    def set_content(
-        self: _InteractionMessageBuilderT, content: undefined.UndefinedOr[str], /
-    ) -> _InteractionMessageBuilderT:
+    def set_content(self, content: undefined.UndefinedOr[str], /) -> Self:
         self._content = str(content) if content is not undefined.UNDEFINED else undefined.UNDEFINED
         return self
 
-    def set_flags(
-        self: _InteractionMessageBuilderT, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /
-    ) -> _InteractionMessageBuilderT:
+    def set_flags(self, flags: typing.Union[undefined.UndefinedType, int, messages.MessageFlag], /) -> Self:
         self._flags = flags
         return self
 
-    def set_tts(self: _InteractionMessageBuilderT, tts: undefined.UndefinedOr[bool], /) -> _InteractionMessageBuilderT:
+    def set_tts(self, tts: undefined.UndefinedOr[bool], /) -> Self:
         self._is_tts = tts
         return self
 
-    def set_mentions_everyone(
-        self: _InteractionMessageBuilderT, state: undefined.UndefinedOr[bool] = undefined.UNDEFINED, /
-    ) -> _InteractionMessageBuilderT:
+    def set_mentions_everyone(self, state: undefined.UndefinedOr[bool] = undefined.UNDEFINED, /) -> Self:
         self._mentions_everyone = state
         return self
 
     def set_role_mentions(
-        self: _InteractionMessageBuilderT,
+        self,
         role_mentions: undefined.UndefinedOr[
             typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool]
         ] = undefined.UNDEFINED,
         /,
-    ) -> _InteractionMessageBuilderT:
+    ) -> Self:
         self._role_mentions = role_mentions
         return self
 
     def set_user_mentions(
-        self: _InteractionMessageBuilderT,
+        self,
         user_mentions: undefined.UndefinedOr[
             typing.Union[snowflakes.SnowflakeishSequence[users.PartialUser], bool]
         ] = undefined.UNDEFINED,
         /,
-    ) -> _InteractionMessageBuilderT:
+    ) -> Self:
         self._user_mentions = user_mentions
         return self
 
@@ -1225,17 +1196,15 @@ def custom_id(self) -> str:
     def components(self) -> typing.Sequence[special_endpoints.ComponentBuilder]:
         return self._components
 
-    def set_title(self: _InteractionModalBuilderT, title: str, /) -> _InteractionModalBuilderT:
+    def set_title(self, title: str, /) -> Self:
         self._title = title
         return self
 
-    def set_custom_id(self: _InteractionModalBuilderT, custom_id: str, /) -> _InteractionModalBuilderT:
+    def set_custom_id(self, custom_id: str, /) -> Self:
         self._custom_id = custom_id
         return self
 
-    def add_component(
-        self: _InteractionModalBuilderT, component: special_endpoints.ComponentBuilder, /
-    ) -> _InteractionModalBuilderT:
+    def add_component(self, component: special_endpoints.ComponentBuilder, /) -> Self:
         self._components.append(component)
         return self
 
@@ -1289,23 +1258,23 @@ def is_nsfw(self) -> undefined.UndefinedOr[bool]:
     def name(self) -> str:
         return self._name
 
-    def set_id(self: _CommandBuilderT, id_: undefined.UndefinedOr[snowflakes.Snowflakeish], /) -> _CommandBuilderT:
+    def set_id(self, id_: undefined.UndefinedOr[snowflakes.Snowflakeish], /) -> Self:
         self._id = snowflakes.Snowflake(id_) if id_ is not undefined.UNDEFINED else undefined.UNDEFINED
         return self
 
     def set_default_member_permissions(
-        self: _CommandBuilderT,
+        self,
         default_member_permissions: typing.Union[undefined.UndefinedType, int, permissions_.Permissions],
         /,
-    ) -> _CommandBuilderT:
+    ) -> Self:
         self._default_member_permissions = default_member_permissions
         return self
 
-    def set_is_dm_enabled(self: _CommandBuilderT, state: undefined.UndefinedOr[bool], /) -> _CommandBuilderT:
+    def set_is_dm_enabled(self, state: undefined.UndefinedOr[bool], /) -> Self:
         self._is_dm_enabled = state
         return self
 
-    def set_is_nsfw(self: _CommandBuilderT, state: undefined.UndefinedOr[bool], /) -> _CommandBuilderT:
+    def set_is_nsfw(self, state: undefined.UndefinedOr[bool], /) -> Self:
         self._is_nsfw = state
         return self
 
@@ -1314,10 +1283,10 @@ def name_localizations(self) -> typing.Mapping[typing.Union[locales.Locale, str]
         return self._name_localizations
 
     def set_name_localizations(
-        self: _CommandBuilderT,
+        self,
         name_localizations: typing.Mapping[typing.Union[locales.Locale, str], str],
         /,
-    ) -> _CommandBuilderT:
+    ) -> Self:
         self._name_localizations = name_localizations
         return self
 
@@ -1357,7 +1326,7 @@ def description(self) -> str:
     def type(self) -> commands.CommandType:
         return commands.CommandType.SLASH
 
-    def add_option(self: _SlashCommandBuilderT, option: commands.CommandOption) -> _SlashCommandBuilderT:
+    def add_option(self, option: commands.CommandOption) -> Self:
         self._options.append(option)
         return self
 
@@ -1372,10 +1341,10 @@ def description_localizations(
         return self._description_localizations
 
     def set_description_localizations(
-        self: _SlashCommandBuilderT,
+        self,
         description_localizations: typing.Mapping[typing.Union[locales.Locale, str], str],
         /,
-    ) -> _SlashCommandBuilderT:
+    ) -> Self:
         self._description_localizations = description_localizations
         return self
 
@@ -1486,6 +1455,10 @@ class _ButtonBuilder(special_endpoints.ButtonBuilder[_ContainerProtoT]):
     _label: undefined.UndefinedOr[str] = attr.field(alias="label", default=undefined.UNDEFINED)
     _is_disabled: bool = attr.field(alias="is_disabled", default=False)
 
+    @property
+    def type(self) -> typing.Literal[component_models.ComponentType.BUTTON]:
+        return component_models.ComponentType.BUTTON
+
     @property
     def style(self) -> typing.Union[int, component_models.ButtonStyle]:
         return self._style
@@ -1503,19 +1476,19 @@ def is_disabled(self) -> bool:
         return self._is_disabled
 
     def set_emoji(
-        self: _ButtonBuilderT,
+        self,
         emoji: typing.Union[snowflakes.Snowflakeish, emojis.Emoji, str, undefined.UndefinedType],
         /,
-    ) -> _ButtonBuilderT:
+    ) -> Self:
         self._emoji_id, self._emoji_name = _build_emoji(emoji)
         self._emoji = emoji
         return self
 
-    def set_label(self: _ButtonBuilderT, label: undefined.UndefinedOr[str], /) -> _ButtonBuilderT:
+    def set_label(self, label: undefined.UndefinedOr[str], /) -> Self:
         self._label = label
         return self
 
-    def set_is_disabled(self: _ButtonBuilderT, state: bool, /) -> _ButtonBuilderT:
+    def set_is_disabled(self, state: bool, /) -> Self:
         self._is_disabled = state
         return self
 
@@ -1603,20 +1576,20 @@ def emoji(self) -> typing.Union[snowflakes.Snowflakeish, emojis.Emoji, str, unde
     def is_default(self) -> bool:
         return self._is_default
 
-    def set_description(self: _SelectOptionBuilderT, value: undefined.UndefinedOr[str], /) -> _SelectOptionBuilderT:
+    def set_description(self, value: undefined.UndefinedOr[str], /) -> Self:
         self._description = value
         return self
 
     def set_emoji(
-        self: _SelectOptionBuilderT,
+        self,
         emoji: typing.Union[snowflakes.Snowflakeish, emojis.Emoji, str, undefined.UndefinedType],
         /,
-    ) -> _SelectOptionBuilderT:
+    ) -> Self:
         self._emoji_id, self._emoji_name = _build_emoji(emoji)
         self._emoji = emoji
         return self
 
-    def set_is_default(self: _SelectOptionBuilderT, state: bool, /) -> _SelectOptionBuilderT:
+    def set_is_default(self, state: bool, /) -> Self:
         self._is_default = state
         return self
 
@@ -1654,6 +1627,10 @@ class SelectMenuBuilder(special_endpoints.SelectMenuBuilder[_ContainerProtoT]):
     _max_values: int = attr.field(alias="max_values", default=1)
     _is_disabled: bool = attr.field(alias="is_disabled", default=False)
 
+    @property
+    def type(self) -> typing.Union[int, component_models.ComponentType]:
+        return self._type
+
     @property
     def custom_id(self) -> str:
         return self._custom_id
@@ -1674,19 +1651,19 @@ def min_values(self) -> int:
     def max_values(self) -> int:
         return self._max_values
 
-    def set_is_disabled(self: _SelectMenuBuilderT, state: bool, /) -> _SelectMenuBuilderT:
+    def set_is_disabled(self, state: bool, /) -> Self:
         self._is_disabled = state
         return self
 
-    def set_placeholder(self: _SelectMenuBuilderT, value: undefined.UndefinedOr[str], /) -> _SelectMenuBuilderT:
+    def set_placeholder(self, value: undefined.UndefinedOr[str], /) -> Self:
         self._placeholder = value
         return self
 
-    def set_min_values(self: _SelectMenuBuilderT, value: int, /) -> _SelectMenuBuilderT:
+    def set_min_values(self, value: int, /) -> Self:
         self._min_values = value
         return self
 
-    def set_max_values(self: _SelectMenuBuilderT, value: int, /) -> _SelectMenuBuilderT:
+    def set_max_values(self, value: int, /) -> Self:
         self._max_values = value
         return self
 
@@ -1713,24 +1690,22 @@ class TextSelectMenuBuilder(
 ):
     """Builder class for text select menus."""
 
-    _type: typing.Union[component_models.ComponentType, int] = component_models.ComponentType.TEXT_SELECT_MENU
+    _type: typing.Literal[component_models.ComponentType.TEXT_SELECT_MENU] = attr.field(
+        default=component_models.ComponentType.TEXT_SELECT_MENU, init=False
+    )
     # Any has to be used here as we can't access Self type in this context
     _options: typing.List[special_endpoints.SelectOptionBuilder[typing.Any]] = attr.field(alias="options", factory=list)
 
     @property
     def options(
-        self: _TextSelectMenuBuilderT,
-    ) -> typing.Sequence[special_endpoints.SelectOptionBuilder[_TextSelectMenuBuilderT]]:
+        self,
+    ) -> typing.Sequence[special_endpoints.SelectOptionBuilder[Self]]:
         return self._options.copy()
 
-    def add_option(
-        self: _TextSelectMenuBuilderT, label: str, value: str, /
-    ) -> special_endpoints.SelectOptionBuilder[_TextSelectMenuBuilderT]:
+    def add_option(self, label: str, value: str, /) -> special_endpoints.SelectOptionBuilder[Self]:
         return _SelectOptionBuilder(menu=self, label=label, value=value)
 
-    def add_raw_option(
-        self: _TextSelectMenuBuilderT, option: special_endpoints.SelectOptionBuilder[_TextSelectMenuBuilderT], /
-    ) -> _TextSelectMenuBuilderT:
+    def add_raw_option(self, option: special_endpoints.SelectOptionBuilder[Self], /) -> Self:
         self._options.append(option)
         return self
 
@@ -1749,15 +1724,15 @@ class ChannelSelectMenuBuilder(
     """Builder class for channel select menus."""
 
     _channel_types: typing.Sequence[channels.ChannelType] = attr.field(alias="channel_types", factory=list)
-    _type: typing.Union[component_models.ComponentType, int] = component_models.ComponentType.CHANNEL_SELECT_MENU
+    _type: typing.Literal[component_models.ComponentType.CHANNEL_SELECT_MENU] = attr.field(
+        default=component_models.ComponentType.CHANNEL_SELECT_MENU, init=False
+    )
 
     @property
     def channel_types(self) -> typing.Sequence[channels.ChannelType]:
         return self._channel_types
 
-    def set_channel_types(
-        self: _ChannelSelectMenuBuilderT, value: typing.Sequence[channels.ChannelType], /
-    ) -> _ChannelSelectMenuBuilderT:
+    def set_channel_types(self, value: typing.Sequence[channels.ChannelType], /) -> Self:
         self._channel_types = value
         return self
 
@@ -1786,6 +1761,10 @@ class TextInputBuilder(special_endpoints.TextInputBuilder[_ContainerProtoT]):
     _min_length: undefined.UndefinedOr[int] = attr.field(alias="min_length", default=undefined.UNDEFINED, kw_only=True)
     _max_length: undefined.UndefinedOr[int] = attr.field(alias="max_length", default=undefined.UNDEFINED, kw_only=True)
 
+    @property
+    def type(self) -> typing.Literal[component_models.ComponentType.TEXT_INPUT]:
+        return component_models.ComponentType.TEXT_INPUT
+
     @property
     def custom_id(self) -> str:
         return self._custom_id
@@ -1818,37 +1797,35 @@ def min_length(self) -> undefined.UndefinedOr[int]:
     def max_length(self) -> undefined.UndefinedOr[int]:
         return self._max_length
 
-    def set_style(
-        self: _TextInputBuilderT, style: typing.Union[component_models.TextInputStyle, int], /
-    ) -> _TextInputBuilderT:
+    def set_style(self, style: typing.Union[component_models.TextInputStyle, int], /) -> Self:
         self._style = component_models.TextInputStyle(style)
         return self
 
-    def set_custom_id(self: _TextInputBuilderT, custom_id: str, /) -> _TextInputBuilderT:
+    def set_custom_id(self, custom_id: str, /) -> Self:
         self._custom_id = custom_id
         return self
 
-    def set_label(self: _TextInputBuilderT, label: str, /) -> _TextInputBuilderT:
+    def set_label(self, label: str, /) -> Self:
         self._label = label
         return self
 
-    def set_placeholder(self: _TextInputBuilderT, placeholder: str, /) -> _TextInputBuilderT:
+    def set_placeholder(self, placeholder: str, /) -> Self:
         self._placeholder = placeholder
         return self
 
-    def set_value(self: _TextInputBuilderT, value: str, /) -> _TextInputBuilderT:
+    def set_value(self, value: str, /) -> Self:
         self._value = value
         return self
 
-    def set_required(self: _TextInputBuilderT, required: bool, /) -> _TextInputBuilderT:
+    def set_required(self, required: bool, /) -> Self:
         self._required = required
         return self
 
-    def set_min_length(self: _TextInputBuilderT, min_length: int, /) -> _TextInputBuilderT:
+    def set_min_length(self, min_length: int, /) -> Self:
         self._min_length = min_length
         return self
 
-    def set_max_length(self: _TextInputBuilderT, max_length: int, /) -> _TextInputBuilderT:
+    def set_max_length(self, max_length: int, /) -> Self:
         self._max_length = max_length
         return self
 
@@ -1879,6 +1856,10 @@ class MessageActionRowBuilder(special_endpoints.MessageActionRowBuilder):
     _components: typing.List[special_endpoints.ComponentBuilder] = attr.field(alias="components", factory=list)
     _stored_type: typing.Optional[component_models.ComponentType] = attr.field(default=None, init=False)
 
+    @property
+    def type(self) -> typing.Literal[component_models.ComponentType.ACTION_ROW]:
+        return component_models.ComponentType.ACTION_ROW
+
     @property
     def components(self) -> typing.Sequence[special_endpoints.ComponentBuilder]:
         return self._components.copy()
@@ -1891,48 +1872,40 @@ def _assert_can_add_type(self, type_: component_models.ComponentType, /) -> None
 
         self._stored_type = type_
 
-    def add_component(
-        self: _MessageActionRowBuilderT, component: special_endpoints.ComponentBuilder, /
-    ) -> _MessageActionRowBuilderT:
+    def add_component(self, component: special_endpoints.ComponentBuilder, /) -> Self:
         self._components.append(component)
         return self
 
     @typing.overload
     def add_button(
-        self: _MessageActionRowBuilderT, style: component_models.InteractiveButtonTypesT, custom_id: str, /
-    ) -> special_endpoints.InteractiveButtonBuilder[_MessageActionRowBuilderT]:
+        self, style: component_models.InteractiveButtonTypesT, custom_id: str, /
+    ) -> special_endpoints.InteractiveButtonBuilder[Self]:
         ...
 
     @typing.overload
     def add_button(
-        self: _MessageActionRowBuilderT,
+        self,
         style: typing.Literal[component_models.ButtonStyle.LINK, 5],
         url: str,
         /,
-    ) -> special_endpoints.LinkButtonBuilder[_MessageActionRowBuilderT]:
+    ) -> special_endpoints.LinkButtonBuilder[Self]:
         ...
 
     @typing.overload
     def add_button(
-        self: _MessageActionRowBuilderT,
+        self,
         style: typing.Union[int, component_models.ButtonStyle],
         url_or_custom_id: str,
         /,
-    ) -> typing.Union[
-        special_endpoints.LinkButtonBuilder[_MessageActionRowBuilderT],
-        special_endpoints.InteractiveButtonBuilder[_MessageActionRowBuilderT],
-    ]:
+    ) -> typing.Union[special_endpoints.LinkButtonBuilder[Self], special_endpoints.InteractiveButtonBuilder[Self],]:
         ...
 
     def add_button(
-        self: _MessageActionRowBuilderT,
+        self,
         style: typing.Union[int, component_models.ButtonStyle],
         url_or_custom_id: str,
         /,
-    ) -> typing.Union[
-        special_endpoints.LinkButtonBuilder[_MessageActionRowBuilderT],
-        special_endpoints.InteractiveButtonBuilder[_MessageActionRowBuilderT],
-    ]:
+    ) -> typing.Union[special_endpoints.LinkButtonBuilder[Self], special_endpoints.InteractiveButtonBuilder[Self],]:
         self._assert_can_add_type(component_models.ComponentType.BUTTON)
         if style in component_models.InteractiveButtonTypes:
             return InteractiveButtonBuilder(container=self, style=style, custom_id=url_or_custom_id)
@@ -1941,47 +1914,47 @@ def add_button(
 
     @typing.overload  # Deprecated overload
     def add_select_menu(
-        self: _MessageActionRowBuilderT,
+        self,
         custom_id: str,
         /,
-    ) -> special_endpoints.TextSelectMenuBuilder[_MessageActionRowBuilderT]:
+    ) -> special_endpoints.TextSelectMenuBuilder[Self]:
         ...
 
     @typing.overload
     def add_select_menu(
-        self: _MessageActionRowBuilderT,
+        self,
         type_: typing.Literal[component_models.ComponentType.TEXT_SELECT_MENU, 3],
         custom_id: str,
         /,
-    ) -> special_endpoints.TextSelectMenuBuilder[_MessageActionRowBuilderT]:
+    ) -> special_endpoints.TextSelectMenuBuilder[Self]:
         ...
 
     @typing.overload
     def add_select_menu(
-        self: _MessageActionRowBuilderT,
+        self,
         type_: typing.Literal[component_models.ComponentType.CHANNEL_SELECT_MENU, 8],
         custom_id: str,
         /,
-    ) -> special_endpoints.ChannelSelectMenuBuilder[_MessageActionRowBuilderT]:
+    ) -> special_endpoints.ChannelSelectMenuBuilder[Self]:
         ...
 
     @typing.overload
     def add_select_menu(
-        self: _MessageActionRowBuilderT,
+        self,
         type_: typing.Union[component_models.ComponentType, int],
         custom_id: str,
         /,
-    ) -> special_endpoints.SelectMenuBuilder[_MessageActionRowBuilderT]:
+    ) -> special_endpoints.SelectMenuBuilder[Self]:
         ...
 
     def add_select_menu(
-        self: _MessageActionRowBuilderT,
+        self,
         type_: typing.Union[component_models.ComponentType, int, str],
         # These have default during the deprecation period for backwards compatibility, as custom_id
         # used to come first
         custom_id: str = "",
         /,
-    ) -> special_endpoints.SelectMenuBuilder[_MessageActionRowBuilderT]:
+    ) -> special_endpoints.SelectMenuBuilder[Self]:
         # custom_id used to come first, so just switch them around if only of them is passed
         if type_ and not custom_id:
             custom_id = str(type_)
@@ -2025,6 +1998,10 @@ class ModalActionRowBuilder(special_endpoints.ModalActionRowBuilder):
         alias="stored_type", init=False, default=None
     )
 
+    @property
+    def type(self) -> typing.Literal[component_models.ComponentType.ACTION_ROW]:
+        return component_models.ComponentType.ACTION_ROW
+
     @property
     def components(self) -> typing.Sequence[special_endpoints.ComponentBuilder]:
         return self._components.copy()
@@ -2037,17 +2014,15 @@ def _assert_can_add_type(self, type_: component_models.ComponentType, /) -> None
 
         self._stored_type = type_
 
-    def add_component(
-        self: _ModalActionRowBuilderT, component: special_endpoints.ComponentBuilder, /
-    ) -> _ModalActionRowBuilderT:
+    def add_component(self, component: special_endpoints.ComponentBuilder, /) -> Self:
         self._components.append(component)
         return self
 
     def add_text_input(
-        self: _ModalActionRowBuilderT,
+        self,
         custom_id: str,
         label: str,
-    ) -> special_endpoints.TextInputBuilder[_ModalActionRowBuilderT]:
+    ) -> special_endpoints.TextInputBuilder[Self]:
         self._assert_can_add_type(component_models.ComponentType.TEXT_INPUT)
         return TextInputBuilder(container=self, custom_id=custom_id, label=label)
 
diff --git a/hikari/interactions/command_interactions.py b/hikari/interactions/command_interactions.py
index fce9bab4..eff6ce0f 100644
--- a/hikari/interactions/command_interactions.py
+++ b/hikari/interactions/command_interactions.py
@@ -46,6 +46,8 @@
 from hikari.internal import attr_extensions
 
 if typing.TYPE_CHECKING:
+    from typing_extensions import Self
+
     from hikari import guilds
     from hikari import permissions as permissions_
     from hikari import users as users_
@@ -101,8 +103,7 @@ class CommandInteractionOption:
     subcommand or group.
     """
 
-    # TODO: use typing.Self here
-    options: typing.Optional[typing.Sequence[CommandInteractionOption]] = attr.field(repr=True)
+    options: typing.Optional[typing.Sequence[Self]] = attr.field(repr=True)
     """Options provided for this option.
 
     Either `CommandInteractionOption.value` or `CommandInteractionOption.options`
@@ -124,18 +125,6 @@ class AutocompleteInteractionOption(CommandInteractionOption):
     even if the option type says otherwise.
     """
 
-    options: typing.Optional[typing.Sequence[AutocompleteInteractionOption]] = attr.field(repr=True)
-    """Options provided for this option.
-
-    Either `AutocompleteInteractionOption.value` or `AutocompleteInteractionOption.options`
-    will be provided with `value` being provided when an option is provided as a
-    parameter with a value and `options` being provided when an option donates a
-    subcommand or group.
-
-    `AutocompleteInteractionOption.is_focused` will be `True` for the value being
-    autocompleted.
-    """
-
 
 @attr_extensions.with_copy
 @attr.define(hash=True, kw_only=True, weakref_slot=False)
diff --git a/hikari/internal/cache.py b/hikari/internal/cache.py
index af307d49..ed9efeb2 100644
--- a/hikari/internal/cache.py
+++ b/hikari/internal/cache.py
@@ -67,6 +67,8 @@
 from hikari.internal import collections
 
 if typing.TYPE_CHECKING:
+    from typing_extensions import Self
+
     from hikari import applications
     from hikari import channels as channels_
     from hikari import components as components_
@@ -320,7 +322,7 @@ def build_entity(self, app: traits.RESTAware, /) -> ValueT:
 
     @classmethod
     @abc.abstractmethod
-    def build_from_entity(cls: typing.Type[DataT], entity: ValueT, /) -> DataT:
+    def build_from_entity(cls, entity: ValueT, /) -> Self:
         """Build a data object from an initialised entity.
 
         Parameters
diff --git a/hikari/internal/collections.py b/hikari/internal/collections.py
index 0245af81..83df4ee9 100644
--- a/hikari/internal/collections.py
+++ b/hikari/internal/collections.py
@@ -24,7 +24,6 @@
 from __future__ import annotations
 
 __all__: typing.Sequence[str] = (
-    "ExtendedMapT",
     "KeyT",
     "ValueT",
     "SnowflakeSet",
@@ -43,7 +42,9 @@
 
 from hikari import snowflakes
 
-ExtendedMapT = typing.TypeVar("ExtendedMapT", bound="ExtendedMutableMapping[typing.Any, typing.Any]")
+if typing.TYPE_CHECKING:
+    from typing_extensions import Self
+
 """Type-hint A type hint used for mapped collection objects."""
 KeyT = typing.TypeVar("KeyT", bound=typing.Hashable)
 """Type-hint A type hint used for the type of a mapping's key."""
@@ -64,7 +65,7 @@ class ExtendedMutableMapping(typing.MutableMapping[KeyT, ValueT], abc.ABC):
     __slots__: typing.Sequence[str] = ()
 
     @abc.abstractmethod
-    def copy(self: ExtendedMapT) -> ExtendedMapT:
+    def copy(self) -> Self:
         """Return a copy of this mapped collection.
 
         Unlike simply doing `dict(mapping)`, this may rely on internal detail
diff --git a/hikari/internal/enums.py b/hikari/internal/enums.py
index fc1def29..9798a6fb 100644
--- a/hikari/internal/enums.py
+++ b/hikari/internal/enums.py
@@ -31,6 +31,9 @@
 import types
 import typing
 
+if typing.TYPE_CHECKING:
+    from typing_extensions import Self
+
 _T = typing.TypeVar("_T")
 _MAX_CACHED_MEMBERS: typing.Final[int] = 1 << 12
 
@@ -161,11 +164,11 @@ def __iter__(cls) -> typing.Iterator[typing.Any]:
         yield from cls._name_to_member_map_.values()
 
     def __new__(
-        mcs: typing.Type[_T],
+        mcs,
         name: str,
         bases: typing.Tuple[typing.Type[typing.Any], ...],
         namespace: typing.Union[typing.Dict[str, typing.Any], _EnumNamespace],
-    ) -> _T:
+    ) -> Self:
         global _Enum
 
         if _Enum is NotImplemented:
@@ -426,11 +429,11 @@ def __prepare__(
 
     @staticmethod
     def __new__(
-        mcs: typing.Type[_T],
+        mcs,
         name: str,
         bases: typing.Tuple[typing.Type[typing.Any], ...],
         namespace: typing.Union[typing.Dict[str, typing.Any], _EnumNamespace],
-    ) -> _T:
+    ) -> Self:
         global _Flag
 
         if _Flag is NotImplemented:
@@ -669,7 +672,7 @@ def value(self) -> int:
         """Return the `int` value of the flag."""
         return self._value_
 
-    def all(self: _T, *flags: _T) -> bool:
+    def all(self, *flags: Self) -> bool:
         """Check if all of the given flags are part of this value.
 
         Returns
@@ -680,7 +683,7 @@ def all(self: _T, *flags: _T) -> bool:
         """
         return all((flag & self) == flag for flag in flags)
 
-    def any(self: _T, *flags: _T) -> bool:
+    def any(self, *flags: Self) -> bool:
         """Check if any of the given flags are part of this value.
 
         Returns
@@ -691,7 +694,7 @@ def any(self: _T, *flags: _T) -> bool:
         """
         return any((flag & self) == flag for flag in flags)
 
-    def difference(self: _T, other: typing.Union[_T, int]) -> _T:
+    def difference(self, other: typing.Union[Self, int]) -> _T:
         """Perform a set difference with the other set.
 
         This will return all flags in this set that are not in the other value.
@@ -700,18 +703,18 @@ def difference(self: _T, other: typing.Union[_T, int]) -> _T:
         """
         return self.__class__(self & ~int(other))
 
-    def intersection(self: _T, other: typing.Union[_T, int]) -> _T:
+    def intersection(self, other: typing.Union[Self, int]) -> _T:
         """Return a combination of flags that are set for both given values.
 
         Equivalent to using the "AND" `&` operator.
         """
         return self.__class__(self._value_ & int(other))
 
-    def invert(self: _T) -> _T:
+    def invert(self) -> Self:
         """Return a set of all flags not in the current set."""
         return self.__class__(self.__class__.__everything__._value_ & ~self._value_)
 
-    def is_disjoint(self: _T, other: typing.Union[_T, int]) -> bool:
+    def is_disjoint(self, other: typing.Union[Self, int]) -> bool:
         """Return whether two sets have a intersection or not.
 
         If the two sets have an intersection, then this returns
@@ -720,18 +723,18 @@ def is_disjoint(self: _T, other: typing.Union[_T, int]) -> bool:
         """
         return not (self & other)
 
-    def is_subset(self: _T, other: typing.Union[_T, int]) -> bool:
+    def is_subset(self, other: typing.Union[Self, int]) -> bool:
         """Return whether another set contains this set or not.
 
         Equivalent to using the "in" operator.
         """
         return (self & other) == other
 
-    def is_superset(self: _T, other: typing.Union[_T, int]) -> bool:
+    def is_superset(self, other: typing.Union[Self, int]) -> bool:
         """Return whether this set contains another set or not."""
         return (self & other) == self
 
-    def none(self: _T, *flags: _T) -> bool:
+    def none(self, *flags: Self) -> bool:
         """Check if none of the given flags are part of this value.
 
         .. note::
@@ -745,7 +748,7 @@ def none(self: _T, *flags: _T) -> bool:
         """
         return not self.any(*flags)
 
-    def split(self: _T) -> typing.Sequence[_T]:
+    def split(self) -> typing.Sequence[Self]:
         """Return a list of all defined atomic values for this flag.
 
         Any unrecognised bits will be omitted for brevity.
@@ -758,7 +761,7 @@ def split(self: _T) -> typing.Sequence[_T]:
             key=lambda m: m._name_,
         )
 
-    def symmetric_difference(self: _T, other: typing.Union[_T, int]) -> _T:
+    def symmetric_difference(self, other: typing.Union[_T, int]) -> Self:
         """Return a set with the symmetric differences of two flag sets.
 
         Equivalent to using the "XOR" `^` operator.
@@ -767,7 +770,7 @@ def symmetric_difference(self: _T, other: typing.Union[_T, int]) -> _T:
         """
         return self.__class__(self._value_ ^ int(other))
 
-    def union(self: _T, other: typing.Union[_T, int]) -> _T:
+    def union(self, other: typing.Union[_T, int]) -> Self:
         """Return a combination of all flags in this set and the other set.
 
         Equivalent to using the "OR" `~` operator.
@@ -791,7 +794,7 @@ def __bool__(self) -> bool:
     def __int__(self) -> int:
         return self._value_
 
-    def __iter__(self: _T) -> typing.Iterator[_T]:
+    def __iter__(self) -> typing.Iterator[Self]:
         return iter(self.split())
 
     def __len__(self) -> int:
@@ -800,7 +803,7 @@ def __len__(self) -> int:
     def __repr__(self) -> str:
         return f"<{self.__class__.__name__}.{self.name}: {self.value!r}>"
 
-    def __rsub__(self: _T, other: typing.Union[int, _T]) -> _T:
+    def __rsub__(self, other: typing.Union[int, _T]) -> Self:
         # This logic has to be reversed to be correct, since order matters for
         # a subtraction operator. This also ensures `int - _T -> _T` is a valid
         # case for us.
diff --git a/hikari/internal/enums.pyi b/hikari/internal/enums.pyi
index 9832676b..79af942f 100644
--- a/hikari/internal/enums.pyi
+++ b/hikari/internal/enums.pyi
@@ -40,32 +40,32 @@ from typing import Sequence as __Sequence
 from typing import TypeVar as __TypeVar
 from typing import Union as __Union
 
-Enum = __enum.Enum
+from typing_extensions import Self as __Self
 
-__FlagT = __TypeVar("__FlagT", bound=__enum.IntFlag)
+Enum = __enum.Enum
 
 class Flag(__enum.IntFlag):
-    def all(self: __FlagT, *flags: __FlagT) -> bool: ...
-    def any(self: __FlagT, *flags: __FlagT) -> bool: ...
-    def difference(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...
-    def intersection(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...
-    def invert(self: __FlagT) -> __FlagT: ...
-    def is_disjoint(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...
-    def is_subset(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...
-    def is_superset(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...
-    def none(self, *flags: __FlagT) -> bool: ...
-    def split(self: __FlagT) -> __Sequence[__FlagT]: ...
-    def symmetric_difference(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...
-    def union(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...
-    def __iter__(self: __FlagT) -> __Iterator[__FlagT]: ...
+    def all(self, *flags: __Self) -> bool: ...
+    def any(self, *flags: __Self) -> bool: ...
+    def difference(self, other: __Union[int, __Self]) -> __Self: ...
+    def intersection(self, other: __Union[int, __Self]) -> __Self: ...
+    def invert(self) -> __Self: ...
+    def is_disjoint(self, other: __Union[int, __Self]) -> bool: ...
+    def is_subset(self, other: __Union[int, __Self]) -> bool: ...
+    def is_superset(self, other: __Union[int, __Self]) -> bool: ...
+    def none(self, *flags: __Self) -> bool: ...
+    def split(self) -> __Sequence[__Self]: ...
+    def symmetric_difference(self, other: __Union[int, __Self]) -> __Self: ...
+    def union(self, other: __Union[int, __Self]) -> __Self: ...
+    def __iter__(self) -> __Iterator[__Self]: ...
     def __len__(self) -> int: ...
     # Aliases
-    def isdisjoint(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...  # is_disjoint
-    def issuperset(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...  # is_superset
-    def symmetricdifference(self: __FlagT, other: __Union[int, __FlagT]) -> __FlagT: ...  # symmetric_difference
-    def issubset(self: __FlagT, other: __Union[int, __FlagT]) -> bool: ...  # is_subset
+    def isdisjoint(self, other: __Union[int, __Self]) -> bool: ...  # is_disjoint
+    def issuperset(self, other: __Union[int, __Self]) -> bool: ...  # is_superset
+    def symmetricdifference(self, other: __Union[int, __Self]) -> __Self: ...  # symmetric_difference
+    def issubset(self, other: __Union[int, __Self]) -> bool: ...  # is_subset
     # '__invert__' is explicitly defined as a special case because it is typed as returning 'int' in typeshed
-    def __invert__(self: __FlagT) -> __FlagT: ...  # invert
+    def __invert__(self) -> __Self: ...  # invert
 
 _V = __TypeVar("_V")
 
diff --git a/hikari/internal/fast_protocol.py b/hikari/internal/fast_protocol.py
index 289267ee..ac6d01e1 100644
--- a/hikari/internal/fast_protocol.py
+++ b/hikari/internal/fast_protocol.py
@@ -29,7 +29,7 @@
 import typing
 
 if typing.TYPE_CHECKING:
-    _T = typing.TypeVar("_T")
+    from typing_extensions import Self
 
 _Protocol: FastProtocolChecking = NotImplemented
 _IGNORED_ATTRS = typing.EXCLUDED_ATTRIBUTES + ["__qualname__", "__slots__"]
@@ -45,11 +45,11 @@ class _FastProtocolChecking(type(typing.Protocol)):
     _attributes_: typing.Tuple[str, ...]
 
     def __new__(
-        cls: typing.Type[_T],
+        cls,
         cls_name: str,
         bases: typing.Tuple[typing.Type[typing.Any], ...],
         namespace: typing.Dict[str, typing.Any],
-    ) -> _T:
+    ) -> Self:
         global _Protocol
 
         if _Protocol is NotImplemented:
@@ -90,7 +90,7 @@ def __new__(
 
         return cls
 
-    def __instancecheck__(self: _T, other: typing.Any) -> bool:
+    def __instancecheck__(self, other: typing.Any) -> bool:
         if not self._is_protocol:
             return super().__instancecheck__(other)
 
diff --git a/hikari/traits.py b/hikari/traits.py
index 118fddeb..0883e6eb 100644
--- a/hikari/traits.py
+++ b/hikari/traits.py
@@ -50,6 +50,8 @@
     import datetime
     from concurrent import futures
 
+    from typing_extensions import Self
+
     from hikari import channels
     from hikari import guilds
     from hikari import intents as intents_
@@ -65,8 +67,6 @@
     from hikari.api import shard as gateway_shard
     from hikari.api import voice as voice_
 
-    _RESTBotAwareT = typing.TypeVar("_RESTBotAwareT", bound="RESTBotAware")
-
 
 @typing.runtime_checkable
 class NetworkSettingsAware(fast_protocol.FastProtocolChecking, typing.Protocol):
@@ -476,15 +476,15 @@ class RESTBotAware(InteractionServerAware, Runnable, fast_protocol.FastProtocolC
 
     @property
     def on_shutdown(
-        self: _RESTBotAwareT,
-    ) -> typing.Sequence[typing.Callable[[_RESTBotAwareT], typing.Coroutine[typing.Any, typing.Any, None]]]:
+        self,
+    ) -> typing.Sequence[typing.Callable[[Self], typing.Coroutine[typing.Any, typing.Any, None]]]:
         """Sequence of the bot's asynchronous shutdown callbacks."""
         raise NotImplementedError
 
     @property
     def on_startup(
-        self: _RESTBotAwareT,
-    ) -> typing.Sequence[typing.Callable[[_RESTBotAwareT], typing.Coroutine[typing.Any, typing.Any, None]]]:
+        self,
+    ) -> typing.Sequence[typing.Callable[[Self], typing.Coroutine[typing.Any, typing.Any, None]]]:
         """Sequence of the bot's asynchronous startup callbacks."""
         raise NotImplementedError
 
diff --git a/hikari/undefined.py b/hikari/undefined.py
index 1d53496f..9bd4a289 100644
--- a/hikari/undefined.py
+++ b/hikari/undefined.py
@@ -36,7 +36,8 @@
 
 import typing
 
-SelfT = typing.TypeVar("SelfT")
+if typing.TYPE_CHECKING:
+    from typing_extensions import Self
 
 
 class UndefinedType:
@@ -47,11 +48,11 @@ class UndefinedType:
     def __bool__(self) -> typing.Literal[False]:
         return False
 
-    def __copy__(self: SelfT) -> SelfT:
+    def __copy__(self) -> Self:
         # This is meant to be a singleton
         return self
 
-    def __deepcopy__(self: SelfT, memo: typing.MutableMapping[int, typing.Any]) -> SelfT:
+    def __deepcopy__(self, memo: typing.MutableMapping[int, typing.Any]) -> Self:
         memo[id(self)] = self
 
         # This is meant to be a singleton


Test patch:
diff --git a/tests/hikari/impl/test_special_endpoints.py b/tests/hikari/impl/test_special_endpoints.py
index a5edf56b..80e8f732 100644
--- a/tests/hikari/impl/test_special_endpoints.py
+++ b/tests/hikari/impl/test_special_endpoints.py
@@ -20,6 +20,8 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
+import typing
+
 import mock
 import pytest
 
@@ -1212,6 +1214,9 @@ def button(self):
             is_disabled=True,
         )
 
+    def test_type_property(self, button):
+        assert button.type is components.ComponentType.BUTTON
+
     def test_style_property(self, button):
         assert button.style is components.ButtonStyle.DANGER
 
@@ -1441,6 +1446,11 @@ class TestSelectMenuBuilder:
     def menu(self):
         return special_endpoints.SelectMenuBuilder(container=mock.Mock(), custom_id="o2o2o2", type=5)
 
+    def test_type_property(self):
+        menu = special_endpoints.SelectMenuBuilder(container=mock.Mock(), type=123, custom_id="hihihi")
+
+        assert menu.type == 123
+
     def test_custom_id_property(self, menu):
         assert menu.custom_id == "o2o2o2"
 
@@ -1481,6 +1491,9 @@ class TestTextSelectMenuBuilder:
     def menu(self):
         return special_endpoints.TextSelectMenuBuilder(container=mock.Mock(), custom_id="o2o2o2")
 
+    def test_type_property(self, menu: special_endpoints.TextSelectMenuBuilder[typing.Any]):
+        assert menu.type is components.ComponentType.TEXT_SELECT_MENU
+
     def test_add_add_option(self, menu):
         option = menu.add_option("ok", "no u")
         option.add_to_menu()
@@ -1513,6 +1526,17 @@ def test_build(self):
 
 
 class TestChannelSelectMenuBuilder:
+    def test_type_property(self):
+        menu = special_endpoints.ChannelSelectMenuBuilder(container=mock.Mock(), custom_id="id")
+        assert menu.type is components.ComponentType.CHANNEL_SELECT_MENU
+
+    def test_set_channel_types(self):
+        menu = special_endpoints.ChannelSelectMenuBuilder(container=mock.Mock(), custom_id="hi")
+
+        menu.set_channel_types([channels.ChannelType.DM, channels.ChannelType.GUILD_FORUM])
+
+        assert menu.channel_types == [channels.ChannelType.DM, channels.ChannelType.GUILD_FORUM]
+
     def test_build(self):
         result = (
             special_endpoints.ChannelSelectMenuBuilder(container=object(), custom_id="o2o2o2")
@@ -1544,6 +1568,9 @@ def text_input(self):
             label="label",
         )
 
+    def test_type_property(self, text_input):
+        assert text_input.type is components.ComponentType.TEXT_INPUT
+
     def test_set_style(self, text_input):
         assert text_input.set_style(components.TextInputStyle.PARAGRAPH) is text_input
         assert text_input.style == components.TextInputStyle.PARAGRAPH
@@ -1623,6 +1650,11 @@ def test_build_partial(self):
 
 
 class TestMessageActionRowBuilder:
+    def test_type_property(self):
+        row = special_endpoints.MessageActionRowBuilder()
+
+        assert row.type is components.ComponentType.ACTION_ROW
+
     def test_components_property(self):
         mock_component = object()
         row = special_endpoints.MessageActionRowBuilder().add_component(mock_component)
@@ -1670,6 +1702,11 @@ def test_build(self):
 
 
 class TestModalActionRow:
+    def test_type_property(self):
+        row = special_endpoints.ModalActionRowBuilder()
+
+        assert row.type is components.ComponentType.ACTION_ROW
+
     def test_add_text_input(self):
         row = special_endpoints.ModalActionRowBuilder()
         menu = row.add_text_input("hihihi", "label")