Override a Built-in Structure
Replace a default class with your own subclass and keep everything strongly typed.
Hoshimi builds every core object through a Structures factory. Swap an entry for your own subclass to add methods or state, and augment CustomizableStructures so the types follow.
The override pattern
import { , } from 'hoshimi';
class extends {
public (): boolean {
return this. > 120;
}
}
. = (...) => new (...);
declare module 'hoshimi' {
interface CustomizableStructures {
: ;
}
}The augmentation is what re-types everything
Assigning to Structures swaps the class at runtime; augmenting CustomizableStructures is what makes
player.filterManager, PlayerStructure and every other reference resolve to your subclass. A local
interface CustomizableStructures in your file does nothing — it has to be inside
declare module 'hoshimi'.
Override several at once
import { , , , } from 'hoshimi';
class extends {}
class extends {}
class extends {}
. = (...) => new (...);
. = (...) => new (...);
. = (...) => new (...);
declare module 'hoshimi' {
interface CustomizableStructures {
: ;
: ;
: ;
}
}Every structure is overridable: Player, Node, NodeManager, Rest, Queue, LyricsManager, FilterManager, Track, UnresolvedTrack, PlayerVoiceState and PlayerStorageAdapter.
Use the structure types
The *Structure type aliases resolve to the final instance type — default or your override — so use them in signatures instead of the concrete class.
import type { , } from 'hoshimi';
function (: ): void {
// Works with the default Player or any custom replacement.
.(`Guild: ${.}`);
}
function (: ): string {
return ..;
}Best practices
- Override structures once during bootstrap, before creating any managers.
- Keep constructor signatures unchanged to stay compatible with the factory.
- Add narrow, domain-specific methods instead of rewriting core flow logic.
- Use
*Structuretypes in signatures to avoid coupling to concrete classes.
Typing data, not classes
To type the requester/userData on tracks or the keys of player.data you do not need a subclass —
see Type your track requester and
Type player.data keys.