-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Problem
In next, we need a clean way to type functions that can accept:
- Specific Discord object types (e.g.,
TextChannel) - OR
Objectfor power users who only have an ID (e.g., from a database)
Currently, this would require verbose union types like TextChannel | Object repeated throughout the codebase.
Why Not Just Accept Snowflake?
We can't simply type functions as accepting Snowflake because Snowflake is a protocol, and protocols use structural typing. This means any class with an .id attribute would be accepted - including other Discord classes that shouldn't be valid for that function.
Example Problem
Consider a function that operates on text channels:
def send_message(channel: Snowflake, content: str) -> None:
...If typed as Snowflake, this would accept:
TextChannel(correct)Object(desired for power users)CategoryChannel(WRONG - categories can't receive messages)User(WRONG - completely different type)- Any other Discord object with
.id(WRONG)
The problem is within the library itself - we need to restrict which specific Discord classes are accepted, not allow all of them just because they implement the Snowflake protocol.
Proposed Solution
Create a generic type alias for the SpecificClass | Object pattern:
type CanBeObject[T: Snowflake] = T | ObjectThen in function signatures:
def send_message(channel: CanBeObject[TextChannel], content: str) -> None:
...This accepts:
TextChannelinstancesObjectinstances (for power users with just an ID)
But rejects at type-check time:
CategoryChannel- Other unrelated Discord objects
Note: CanBeObject is just a placeholder name - a better name should be chosen.
Benefits
- Type safety: Only accepts the intended Discord class(es), not all Snowflakes
- Power user flexibility: Still allows
Objectfor cases where only an ID is available - Maintainability: Reduces repetition of
SpecificClass | Objectthroughout the codebase - Clear intent: Explicit about which Discord types are valid
Context
Discussed as part of next Snowflake redesign to balance API flexibility with type safety.
References: