TypeScript接口中描述的对象的属性能否在其声明中实现接口本身



我知道这可能是一个奇怪的请求,但在我的情况下,它非常适合。

我有一个名为layer的对象,它可以是这样的:

const layer = {
Title: 'parent title',
Name: 'parent name',
Layer: {
Title: 'child title'
}
}

它具有强制性的Title属性以及可选的NameLayer属性。

在存在Layer属性的情况下,它具有刚才描述的相同特性(因此,它可能具有其他嵌套的Layer(。

我需要为它定义一个接口,我认为这样的东西可能会起作用:

interface LayerInterface {
Title: string;
Name?: string;
Layer?: LayerInterface;
}

我的问题是,我是否可以使用LayerInterface作为Layer属性的类型,该属性在LayerInterface本身中定义。

如果可以用这种或另一种简单的方式来做,我就是古玩。

是的,您的递归接口定义:

interface LayerInterface {
Title: string;
Name?: string;
Layer?: LayerInterface;
}

编译成功,意味着你想要它意味着什么:

function processLayer(layer: LayerInterface) {}
processLayer(layer); // okay
const badLayer = { Title: "", Name: "", Layer: { Title: 123, Name: false } }
processLayer(badLayer); // error!
// --------> ~~~~~~~~
/* Argument of type
'{ Title: string; Name: string; Layer: { Title: number; Name: boolean; }; }' 
is not assignable to parameter of type 'LayerInterface'. 
*/

您可以看到,由于嵌套的Layer对象的TitleName属性的类型错误,badLayer无法与LayerInterface匹配。


请注意,这根本不是一个奇怪的请求;许多常用的接口和类至少在某种程度上是这样工作的。任何树结构,如DOM,都会有一个类型定义,其中它的一些属性和方法会引用所定义的类型。

DOMElement节点具有children属性,表示Element节点的类似数组的集合,允许您编写递归元素处理函数:

function processElement(elem: Element) {
console.log(elem.nodeName);
for (let i = 0; i < elem.children.length; i++) {
processElement(elem.children[i]);
}
}

关于文档:

它看起来像";官方的";说明您可以为(越来越过时的(TypeScript Spec:中的接口执行此操作的文档

类和接口可以在其内部结构中引用自己,从而创建具有无限嵌套的递归类型。例如,类型

interface A { next: A; }

包含"next"属性的无限嵌套序列。

它也适用于类型别名,如手册中关于类型别名的部分所述:

我们也可以在属性中有一个引用自身的类型别名:

type Tree<T> = {
value: T;
left: Tree<T>;
right: Tree<T>;
}

好的,希望能有所帮助;祝你好运

游乐场链接到代码

最新更新