Typescript - 使用嵌套属性扩展另一个接口的接口 [英] Typescript - interface extending another interface with nested properties

查看:45
本文介绍了Typescript - 使用嵌套属性扩展另一个接口的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似的界面:

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

如何扩展它,以便向结构添加一些新属性,而无需重复我自己?我是否必须为结构创建一个新的接口并扩展它并使用新的结构接口创建一个新的模块,或者是否有其他一些语法来实现这一点?

How can I extend it, so that I add some new properties to structure, without repeating myself? Do I have to make a new interface for structure and extend that and make a new Module with the new structure interface or is there some other syntax to achieve this?

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

Ideally, I would just write something like:

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

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

谢谢!

推荐答案

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

Interfaces can't add to the types of members in the base interface (at least not directly). You can use an intersection type instead:

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: ''
    }
}

它们的行为应该与接口类似,它们可以由类实现,并且在您为它们分配对象文字时会被检查.

They should behave similarly to interfaces, they can be implemented by classes and they will get checked when you assign object literals to them.

你也可以用接口来做,但它有点冗长,并且暗示使用类型查询来获取字段的原始类型,并再次获得一个交集:

You can also do it with interfaces but it's a bit more verbose, and implies using a type query to get the original type of the field, and again an intersection:

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

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

真正冗长的选项(虽然在某些方面更容易理解)当然只是为结构定义一个单独的接口:

The really verbose option (although in some ways simpler to understand) is of course to just define a separate interface for structure:

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: ''
    }
}

编辑

按照 pe @jcalz 的建议,我们也可以让模块接口通用,并传入合适的结构接口:

As pe @jcalz suggestion, we could also make the module interface generic, and pass in the apropriate structure interface:

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 - 使用嵌套属性扩展另一个接口的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆