Typescript 不同类型块的结构类型

Typescript 不同类型块的结构类型,typescript,Typescript,我正在尝试设计一个类似CMS的块系统,其中输入是一些JSON: [{ 键入:“标题”, 文字:“你好” }, { 类型:“说明”, 案文:“世界” }, { 键入:“按钮”, 文字:“点击我”, href:“/” }] 我会这样定义“块”型系统: 命名空间块{ 接口标题{ 类型:“标题”; 文本:字符串; } 接口描述{ 类型:“说明”; 文本:字符串; } 界面按钮{ 类型:“按钮”; 文本:字符串; href:string; 颜色?:字符串; } } 我该如何构造它,以便能够传递一个

我正在尝试设计一个类似CMS的块系统,其中输入是一些JSON:

[{
键入:“标题”,
文字:“你好”
}, {
类型:“说明”,
案文:“世界”
}, {
键入:“按钮”,
文字:“点击我”,
href:“/”
}]
我会这样定义“块”型系统:

命名空间块{
接口标题{
类型:“标题”;
文本:字符串;
}
接口描述{
类型:“说明”;
文本:字符串;
}  
界面按钮{
类型:“按钮”;
文本:字符串;
href:string;
颜色?:字符串;
}
}
我该如何构造它,以便能够传递一个通用的“块”类型,该类型将根据
类型进行类型检查
?或者这是一种错误的结构方式

interface Page {
   blocks: Block[]
}

interface Block extends AnyOfThoseBlocks { // how would I extend all types of the namespace?
   blocks?: Block[]; // blocks can contain nested other blocks
}

我认为您希望将JSON直接解析为符合这些接口的普通对象,而不是从普通对象中加载具体的类

从结构上看,您的
标题
说明
等接口都需要扩展
接口,而不是相反。这样,它们将继承
属性。因此,也许:

interface Block {
    type: string;
    blocks: Block[];
}
namespace Blocks {
    export interface Title extends Block { type: 'title'; /* ... */ }
    export interface Description extends Block { type: 'description'; /* ... */ }
    export interface Button extends Block { type: 'button'; /* ... */ }
}
如果在某个地方有类型为
Block
的对象,则可以检查其
类型
字段,并根据该字段将其强制转换到相应的界面:

function logHref(block: Block): void {
    if (block.type === 'button') {
        console.log((block as Blocks.Button).href);
    }
}
请记住,这样做并不能实现真正的类型安全,因为JSON可能会有一个格式错误的对象,如
{“type”:“button”,“text”:“Hello World”}
(缺少
href
)。为了安全起见,您可以使用或类似的工具