Typescript 允许对 mixins 使用适当的多重继承,但无法创建 delcaration 文件
Typescript allows to use proper multiple inheritance with mixins, but fails to create delcaration files
我在 TypeScript 中玩弄 "multiple inheritances" 或者更确切地说,我对 mixin 有了很好的理解。在走了很多弯路之后,我发现最简单的方法是尽可能少地进行显式转换,并且能够创建如下所示的东西(完整的示例可以在 gist 中找到)。
我的问题是:为什么 TypeScript 允许我构建它,但无法为此创建声明文件?
export function TaggedMixin<Super extends Ctor>(superClass: Super) {
class Tagged extends superClass {
public static TAG_PUBLIC: string;
protected static TAG_PROTECTED: string;
private static TAG_PRIVATE: string;
public tag_public!: string;
protected tag_protected!: number;
private tag_private!: number;
}
return Tagged;
}
const Tagged = TaggedMixin(class {
public static ANON_PUBLIC: string;
protected static ANON_PROTECTED: string;
private static ANON_PRIVATE: string;
public anon_public!: string;
protected anon_protected!: number;
private anon_private!: number;
});
class TaggedClass extends Tagged {
constructor() {
super();
TaggedClass.ANON_PUBLIC;
TaggedClass.ANON_PROTECTED;
TaggedClass.TAG_PUBLIC;
TaggedClass.TAG_PROTECTED;
this.anon_public;
this.anon_protected;
this.tag_public;
this.tag_protected;
}
}
编辑:
TS 无法创建声明文件的错误:
Property 'tag_protected' of exported class expression may not be private or protected.ts(4094)
Property 'tag_private' of exported class expression may not be private or protected.ts(4094)
Property 'TAG_PROTECTED' of exported class expression may not be private or protected.ts(4094)
Property 'TAG_PRIVATE' of exported class expression may not be private or protected.ts(4094)
发射声明和混入有限制。 Class 表达式不能有私有成员或受保护成员,因为如 here 所述:
exported anonymous classes can't have private or protected members if declaration emit is enabled, because there's no way to represent that in a .d.ts file.
Typescript 将 mixin 的实例类型表示为对象类型,并且对象类型不能具有标记为 private
或 protected
的成员,因此会出现错误。
删除非 public 成员将解决问题。
您还可以添加一些手动输入和 class 声明,这将使您接近目标:
type Ctor = new (...a: any[]) => any
declare class TaggedMixinInstance { // just a dummy, never call new TaggedMixinInstance() or extend this directly
public tag_public: string;
protected tag_protected: number;
private tag_private: number;
}
export function TaggedMixin<Super extends Ctor>(superClass: Super): {
new(...a: any[]): TaggedMixinInstance;
TAG_PUBLIC: string
} & Super {
class Tagged extends superClass {
public static TAG_PUBLIC: string;
protected static TAG_PROTECTED: string;
private static TAG_PRIVATE: string;
public tag_public!: string;
protected tag_protected!: number;
private tag_private!: number;
}
return Tagged;
}
const Tagged = TaggedMixin(class {
public static ANON_PUBLIC: string;
protected static ANON_PROTECTED: string;
private static ANON_PRIVATE: string;
public anon_public!: string;
protected anon_protected!: number;
private anon_private!: number;
});
class TaggedClass extends Tagged {
constructor() {
super();
TaggedClass.ANON_PUBLIC;
TaggedClass.ANON_PROTECTED;
TaggedClass.TAG_PUBLIC;
TaggedClass.TAG_PROTECTED; // still an error
this.anon_public;
this.anon_protected;
this.tag_public;
this.tag_protected;
}
}
我在 TypeScript 中玩弄 "multiple inheritances" 或者更确切地说,我对 mixin 有了很好的理解。在走了很多弯路之后,我发现最简单的方法是尽可能少地进行显式转换,并且能够创建如下所示的东西(完整的示例可以在 gist 中找到)。
我的问题是:为什么 TypeScript 允许我构建它,但无法为此创建声明文件?
export function TaggedMixin<Super extends Ctor>(superClass: Super) {
class Tagged extends superClass {
public static TAG_PUBLIC: string;
protected static TAG_PROTECTED: string;
private static TAG_PRIVATE: string;
public tag_public!: string;
protected tag_protected!: number;
private tag_private!: number;
}
return Tagged;
}
const Tagged = TaggedMixin(class {
public static ANON_PUBLIC: string;
protected static ANON_PROTECTED: string;
private static ANON_PRIVATE: string;
public anon_public!: string;
protected anon_protected!: number;
private anon_private!: number;
});
class TaggedClass extends Tagged {
constructor() {
super();
TaggedClass.ANON_PUBLIC;
TaggedClass.ANON_PROTECTED;
TaggedClass.TAG_PUBLIC;
TaggedClass.TAG_PROTECTED;
this.anon_public;
this.anon_protected;
this.tag_public;
this.tag_protected;
}
}
编辑:
TS 无法创建声明文件的错误:
Property 'tag_protected' of exported class expression may not be private or protected.ts(4094)
Property 'tag_private' of exported class expression may not be private or protected.ts(4094)
Property 'TAG_PROTECTED' of exported class expression may not be private or protected.ts(4094)
Property 'TAG_PRIVATE' of exported class expression may not be private or protected.ts(4094)
发射声明和混入有限制。 Class 表达式不能有私有成员或受保护成员,因为如 here 所述:
exported anonymous classes can't have private or protected members if declaration emit is enabled, because there's no way to represent that in a .d.ts file.
Typescript 将 mixin 的实例类型表示为对象类型,并且对象类型不能具有标记为 private
或 protected
的成员,因此会出现错误。
删除非 public 成员将解决问题。
您还可以添加一些手动输入和 class 声明,这将使您接近目标:
type Ctor = new (...a: any[]) => any
declare class TaggedMixinInstance { // just a dummy, never call new TaggedMixinInstance() or extend this directly
public tag_public: string;
protected tag_protected: number;
private tag_private: number;
}
export function TaggedMixin<Super extends Ctor>(superClass: Super): {
new(...a: any[]): TaggedMixinInstance;
TAG_PUBLIC: string
} & Super {
class Tagged extends superClass {
public static TAG_PUBLIC: string;
protected static TAG_PROTECTED: string;
private static TAG_PRIVATE: string;
public tag_public!: string;
protected tag_protected!: number;
private tag_private!: number;
}
return Tagged;
}
const Tagged = TaggedMixin(class {
public static ANON_PUBLIC: string;
protected static ANON_PROTECTED: string;
private static ANON_PRIVATE: string;
public anon_public!: string;
protected anon_protected!: number;
private anon_private!: number;
});
class TaggedClass extends Tagged {
constructor() {
super();
TaggedClass.ANON_PUBLIC;
TaggedClass.ANON_PROTECTED;
TaggedClass.TAG_PUBLIC;
TaggedClass.TAG_PROTECTED; // still an error
this.anon_public;
this.anon_protected;
this.tag_public;
this.tag_protected;
}
}