Problem
In next, we need a clean way to type functions that can accept:
- Specific Discord object types (e.g.,
TextChannel)
- OR
Object for 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 | Object
Then in function signatures:
def send_message(channel: CanBeObject[TextChannel], content: str) -> None:
...
This accepts:
TextChannel instances
Object instances (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
Object for cases where only an ID is available
- Maintainability: Reduces repetition of
SpecificClass | Object throughout 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:
Problem
In next, we need a clean way to type functions that can accept:
TextChannel)Objectfor power users who only have an ID (e.g., from a database)Currently, this would require verbose union types like
TextChannel | Objectrepeated throughout the codebase.Why Not Just Accept Snowflake?
We can't simply type functions as accepting
Snowflakebecause Snowflake is a protocol, and protocols use structural typing. This means any class with an.idattribute 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:
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).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
Snowflakeprotocol.Proposed Solution
Create a generic type alias for the
SpecificClass | Objectpattern:Then in function signatures:
This accepts:
TextChannelinstancesObjectinstances (for power users with just an ID)But rejects at type-check time:
CategoryChannelNote:
CanBeObjectis just a placeholder name - a better name should be chosen.Benefits
Objectfor cases where only an ID is availableSpecificClass | Objectthroughout the codebaseContext
Discussed as part of next Snowflake redesign to balance API flexibility with type safety.
References: