我有一个类似的界面
public void DoWork()
{
List<MyStruct> list;
{ // just this
HashSet<MyStruct> hashSet = LoadALotOfStructs();
list = hashSet.ToList();
} // and this
// Lot of code that can not use the hashSet anymore
}
如何扩展它,以便在不重复自己的情况下向结构添加一些新属性?我是否必须为结构创建一个新的接口并对其进行扩展,并使用新的结构接口创建一个新的Module,还是有其他语法可以实现此目的?
理想情况下,我会写类似这样的东西:
export interface Module {
name: string;
data: any;
structure: {
icon: string;
label: string;
...
}
}
谢谢!
答案 0 :(得分:1)
接口不能添加到基本接口中的成员类型(至少不是直接添加)。您可以改用交叉点类型:
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: ''
}
}
修改
按照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: ''
}
}