Интерфейсы не могут добавлять типы элементов в базовый интерфейс (по крайней мере, не напрямую).Вместо этого вы можете использовать тип пересечения:
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;
}
}
Действительно подробный вариант (хотя в некоторыхпроще понять), конечно, просто определить отдельный интерфейс для структуры:
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, мы могли бы также сделатьинтерфейс модуля универсален и передается в интерфейс соответствующей структуры:
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: ''
}
}