I have the following ItemBase interface and multiple other recursive xItem interfaces that extend from it:
interface ItemBase<Children extends ItemBase<Children>> {
x: string;
y: number;
children: Children[];
}
interface FooItem extends ItemBase<FooItem> {
foo: boolean;
}
interface BarItem extends ItemBase<BarItem> {
bar: "b" | "a" | "r";
}
I would now like to reference ItemBase with itself as its own argument:
const transformItem = (item: ItemBase<ItemBase>) => { ... }
// ^
// TS2314: Generic type 'ItemBase ' requires 1 type argument(s).
but this doesn't work, because since I didn't specify the inner ItemBase's argument (and obviously can't keep specifying those to infinity).
Even better would be providing itself as ItemBase's default argument... I tried two ways, but each of them runs into its own error:
interface ItemBase<Children extends ItemBase<Children> = ItemBase<Children>> {
// ^
// TS2744: Type parameter defaults can only reference previously declared type parameters.
x: string;
y: number;
children: Children[];
}
interface ItemBase<Children extends ItemBase<Children> = ItemBase> {
// ^
// TS2716: Type parameter 'Children' has a circular default.
x: string;
y: number;
children: Children[];
}
An obvious workaround would be creating a separate interface to express my self-referencing base:
interface BaseItem extends ItemBase<BaseItem> {}
const transformItem = (item: BaseItem) => { ... }
but that's more of a hack, since the other items don't really inherit from it.
What are some other options I have?