我有一套可以“天真地”的课程。表示为钻石:
OneBase
/ \
OneDer TwoBase
\ /
TwoDer
[注意 - 由于@mitch评论已更改名称。]
事实上,One
和Two
是" base"类,除OneDer
和TwoDer
之外还有几个不同的类,它们使用相同的模式从它们派生。假设(OneBase,TwoBase)
位于模块base
中,(OneDer, TwoDer)
位于模块derived
中。
同样OneBase
包含一个Part
个结构,其中包含TwoBase
个实例;在OneDer
中,等效结构应包含TwoDer
实例。
我将TwoBase
转换为mixin,以下代码编译:
模块base
:
export type Constructor<T> = new(...args: any[]) => T
export class One {
p: Part
constructor (readonly a: number) {}
}
export class TwoPre extends One {
constructor (readonly a: number, readonly c: M[]) {
super(a)
}
}
export function TwoMix<
T extends Constructor<TwoPre>> (Base: T): Constructor<TwoPre> {
class Two extends Base {
}
return Two
}
export const Two = TwoMix(TwoPre)
export interface Part {
u: typeof Two
}
模块derived
:
import { Part, One, TwoMix } from './base'
export class OneDer extends One {
p: Part
}
export class TwoDerPre extends OneDer {
constructor (readonly a: number, readonly c: M[]) {
super(a)
}
}
export const TwoDer = TwoMix(TwoDerPre)
请注意TwoPre
和TwoDerPre
是必要的,因为&#34;天真&#34; Two
具有与One
不同的构造函数签名,mixin函数无法定义
构造函数。这有点痛苦,因为它不必要地增加了原型链 - 所以变通方法很受欢迎。除此之外,mixin
确实强制执行我想要的方法解析顺序。
当我尝试强制PartDer
与Part
之间的差异时,真正的问题出现了;此版本的模块derived
无法编译:
import { Part, One, TwoMix } from './base'
export class OneDer extends One {
p: PartDer
}
export class TwoDerPre extends OneDer {
constructor (readonly a: number, readonly c: M[]) {
super(a)
}
}
export const TwoDer = TwoMix(TwoDerPre)
export interface PartDer extends Part {
u: typeof TwoDer
}
我收到错误:
src/derived.ts(13,14): error TS7022: 'TwoDer' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
src/derived.ts(15,3): error TS2502: 'u' is referenced directly or indirectly in its own type annotation.
我想知道为什么编译器抱怨这个循环时它没有在base
中抱怨它,我能做些什么呢?
注意这是我能想到的表达问题的最短路径。当然,TwoDer
实际上不仅仅是mixin的实例化,因此derived
末尾的代码看起来更像是:
export class TwoDer extends TwoMix(TwoDerPre) {
}
export interface PartDer extends Part {
u: TwoDer
}
使用此版本,我会遇到稍微不同的错误:
src/derived.ts(17,6): error TS2304: Cannot find name 'TwoDer'.
src/derived.ts(17,6): error TS4033: Property 'u' of exported interface has or is using private name 'TwoDer'.
如果我将PartDer
转换为使用typeof TwoDer
,我会收到原始错误:
export interface PartDer extends Part {
u: typeof TwoDer
}
答案 0 :(得分:1)
我无法理解你想要做的事情,但TypeScript在这里丢失了一些类型信息:
export const TwoDer = TwoMix(TwoDerPre)
这导致了效果。您可以通过添加一些类型信息来解决此特定问题:
export const TwoDer: Constructor<TwoPre> = TwoMix(TwoDerPre)
这清除了'u' is referenced directly or indirectly in its own type annotation.
混淆的问题。我不知道它是否能让一切对你有用。