如何使用可选类型定义自引用可扩展接口



假设我有菜单界面:

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;

最新更新