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: ''
}
}
Edit
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: ''
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…