角的Type<T>
是一个糟糕的 API。您是许多被其不负责任的命名所误导的人之一(见评论)。Type<T>
真正的意思是可建造的。它是您可以调用的值的类型new
.
By.directive
需要一个value不是一种类型。该值的类型可以通过以下方式调用new
,可以构造的东西。这意味着一个类或一个函数。
然而,你can写出你想要的函数。
这是我的写法。
export function getDirective<T>(
hostFixture: ComponentFixture<any>,
ComponentConstructor: new (...args: unknown[]) => T
): T {
const debugElement = hostFixture.debugElement.query(By.directive(ComponentConstructor));
return debugElement && debugElement.componentInstance || undefined;
}
然后这样称呼它
const instance = getDirective(fixture, MyComponent);
Remarks:
TypeScript 类型纯粹是设计时构造。该语言的整个类型系统经过精心设计,可在转译过程中完全擦除,特别是不会影响程序的运行时行为。
为什么我说这个名字Type<T>
是不负责任吗?因为成千上万的程序员是在 Angular 的背景下第一次学习 TypeScript。通过将类型命名为 Type,他们使事情变得非常容易误解。
这尤其重要,因为类型Type<T>
通常归因于一个类的值,许多人已经将类型与 TypeScript 和普通 JavaScript 中的类混淆了。
Angular 希望将这些概念合并起来,它wishesJavaScript 中的类与许多其他语言中的类一样,但它们根本不是。值得注意的是,像我更喜欢的 Aurelia 这样的框架也鼓励这种合并,但是,因为它们不attempt强制使用 TypeScript,并且它们允许通过类上的属性指定依赖项(也许具有讽刺意味的是,以 AngularJS 的方式),混淆的可能性较小。无论如何,TypeScript 类型、ECMAScript 类和依赖项注入是完全正交的概念。
鉴于 TypeScript 的性质(仅提供设计时类型),这会导致严重的混乱。
有趣的是,Angular 团队专门为 Angular 2 的开发设计了自己的编程语言,称为 @Script。@Script 是 JavaScript 和 TypeScript 的衍生品,它的特点是添加了一定程度的类型具体化,同时避免了装饰器对于当时竞争的注释特征。他们在 2014 年底放弃了这种语言,选择使用 TypeScript。
不过,有时我认为启发 @Script 的哲学仍然影响着 Angular。