假设我有菜单界面:
interface IMenuBase {
id: number;
title: string;
items: IMenuBase[]; <- children
}
现在我想扩展它。为此,我定义了另一个接口:
interface ICustomMenu extend IMenuBase {
concrete: string;
}
问题是,items
仍然是一个IMenuBase。
我试图以这种方式解决它:
interface IMenuBase<T extends IMenuBase<T>> {
id: number;
title: string;
items: T[];
}
interface ICustomMenu extends IMenuBase<ICustomMenu> {
concrete: string;
}
但是现在我希望能够在没有类型的情况下使用IMenuBase。这是我的游乐场。
你有两种可能性。您可以使用当前的解决方案,使基类泛型,并为类型参数添加默认值:
interface IMenuBase<T extends IMenuBase<T> = IMenuBase<T>> {
id: number;
title: string;
items: T[];
}
interface ICustomMenu extends IMenuBase<ICustomMenu> {
concrete: string;
}
const testBase = {} as IMenuBase;
testBase.items[0].items[0].id;
const testConcrete = {} as ICustomMenu;
testConcrete.items[0].items[0].concrete;
上面的代码有一个问题,它最多只能用于 3 个级别(我认为这是默认的递归性受到编译器的限制)
更好的选择可能是使用多态this
来指定子类型与当前类型属于同一类型,无论该类型是什么:
interface IMenuBase {
id: number;
title: string;
items: this[];
}
interface ICustomMenu extends IMenuBase {
concrete: string;
}
const testBase = {} as IMenuBase;
testBase.items[0].items[0].id;
const testConcrete = {} as ICustomMenu;
testConcrete.items[0].items[0].concrete;