我有这样一个界面:

export interface Module {
  name: string;
  data: any;
  structure: {
    icon: string;
    label: string;
    ...
  }
}

如何扩展它,以便在不重复自己的情况下向 struct 中添加一些新属性?我是否必须为 struct 创建一个新的接口,并对其进行扩展,然后使用新的 struct 接口创建一个新的模块,或者是否有其他语法来实现这一点?

理想情况下,我会写下这样的内容:

export interface DataModule extends Module {
  structure: {
    visible: boolean;
  }
}

export interface UrlModule extends Module {
  structure: {
    url: string;
  }
}

谢谢

推荐答案

接口不能添加到基本接口中的成员类型(至少不能直接添加).可以改用交叉点类型:

export interface Module {
name: string;
data: any;
    structure: {
        icon: string;
        label: string;
    }
}

export type DataModule = Module & {
    structure: {
        visible: boolean;
    }
}

export type UrlModule = Module & {
    structure: {
        url: string;
    }
}

let urlModule: UrlModule = {
    name: "",
    data: {},
    structure: {
        icon: '',
        label: '',
        url: ''
    }
}

它们的行为应该类似于接口,它们可以由类实现,当您为它们分配对象文本时,它们将得到判断.

您也可以使用接口来实现这一点,但它有点冗长,并且意味着使用类型查询来获取字段的原始类型,以及一个交集:

export interface DataModule extends Module {
    structure: Module['structure'] & {
        visible: boolean;
    }
}

export interface UrlModule extends Module {
    structure: Module['structure'] & {
        url: string;
    }
}

真正详细的选项(虽然在某些方面更容易理解)当然是为 struct 定义一个单独的接口:

export interface IModuleStructure {        
    icon: string;
    label: string;
}
export interface Module {
    name: string;
    data: any;
    structure: IModuleStructure
}
export interface IDataModuleStructure extends IModuleStructure{
    visible: boolean;
}
export interface DataModule extends Module {
    structure: IDataModuleStructure 
}
export interface IUrlModuleStructure extends IModuleStructure {
    url: string;
}
export interface UrlModule extends Module {
    structure: IUrlModuleStructure
}
let urlModule: UrlModule = {
    name: "",
    data: {},
    structure: {
        icon: '',
        label: '',
        url: ''
    }
}

Edit

根据pe@jcalz的建议,我们还可以使模块接口通用,并传递适当的 struct 接口:

export interface IModuleStructure {        
    icon: string;
    label: string;
}
export interface Module<T extends IModuleStructure = IModuleStructure> {
    name: string;
    data: any;
    structure: T
}
export interface IDataModuleStructure extends IModuleStructure{
    visible: boolean;
}
export interface DataModule extends Module<IDataModuleStructure> {
}
export interface IUrlModuleStructure extends IModuleStructure {
    url: string;
}
export interface UrlModule extends Module<IUrlModuleStructure> {
}
let urlModule: UrlModule = { // We could also just use Module<IUrlModuleStructure>
    name: "",
    data: {},
    structure: {
        icon: '',
        label: '',
        url: ''
    }
}

Typescript相关问答推荐

React Router SR:useLocate()只能在路由组件的上下文中使用

对可变位置的父对象的TypScript空判断

Angular 17 -如何使用新的@if语法在对象中使用Deliverc值

类型断言添加到类型而不是替换

在TypeScript中使用泛型的灵活返回值类型

忽略和K的定义

如何在Typescript 中输入两个相互关联的变量?

当方法参数和返回类型不相互扩展时如何从类型脚本中的子类推断类型

使用数组作为类型中允许的键的列表

如何编写在返回函数上分配了属性的类型安全泛型闭包

如何正确调用创建的类型?

如何创建由空格连接的多个字符串的类型

如何在Angular 服务中制作同步方法?

回调函数中的TypeScrip类型保护返回Incorect类型保护(具有其他未定义类型的返回保护类型)

是否将Angular *ngFor和*ngIf迁移到新的v17语法?

如何在Reaction 18、Reaction-Rout6中的导航栏中获取路由参数

如何使用IsEqual创建断言类型相等的实用程序

如何填写Partial的一些属性并让类型系统知道它?

必须从注入上下文调用Angular ResolveFn-inject()

如何按成员资格排除或 Select 元组?