![](/img/trans.png)
[英]Angular, pass generic type into another function. How to typed param?
[英]Angular in Typescript: how to pass generic Type to function
使用 Typescript 编写 Angular 5 单元测试,我有一个函数可以查询 DOM 并在找到时返回MyComponent
类的实例:
function getMyComponent(hostFixture: ComponentFixture<any>): MyComponent {
const debugElement = hostFixture.debugElement.query(By.directive(MyComponent));
return (debugElement && debugElement.componentInstance) || null;
}
这完美无缺。 现在我想概括一下这个函数,以便它可以按需查询任何类型。 我想这可以用泛型类型来完成。函数会像这样调用:
const instance: MyComponent = getDirective<MyComponent>(fixture);
我无法让它工作; 这是损坏的功能:
function getDirective<T>(hostFixture: ComponentFixture<any>): T {
const debugElement = hostFixture.debugElement.query(By.directive(T));
return (debugElement && debugElement.componentInstance) || null;
}
函数中的第一行抛出错误:
TS2693:'T' 仅指一种类型,但在此处用作值
这里的正确语法是什么? 我正在调用的 Angular 函数 -- By.directive()
-- 接受类型为Type<any>
的参数,并在此处记录
Angular 的Type<T>
是一个糟糕的 API。 您是许多被其坦率不负责任的命名误导的人之一(见评论)。 Type<T>
真正意味着可构造。 它是您可以使用new
调用的值的类型。
By.directive
接受一个值而不是一个类型。 该值的类型是可以用new
调用的,可以构造的。 这意味着一个类或一个函数。
但是,您可以编写您想要的功能。
这就是我的写法。
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);
评论:
TypeScript 类型是纯粹的设计时构造。 该语言的整个类型系统经过精心设计,可以在编译期间完全擦除,尤其是对程序的运行时行为没有影响。
为什么说Type Type<T>
这个名字不负责任呢? 因为成千上万的程序员是第一次在 Angular 的上下文中学习 TypeScript。 通过命名一个类型 Type,他们让事情变得很容易被误解。
这一点尤其重要,因为Type<T>
通常被赋予一个类的值,并且许多人已经将类型与 TypeScript 和 vanilla JavaScript 中的类混淆了。
Angular 希望将这些概念混为一谈,它希望JavaScript 中的类与许多其他语言中的类型一样,但事实并非如此。 值得注意的是,我更喜欢 Aurelia 之类的框架也鼓励这种混淆,但是,因为它们不尝试强制使用 TypeScript,并且因为它们允许通过类上的属性来指定依赖项(可能具有讽刺意味的是,在方式或 AngularJS 中,混淆无论如何,TypeScript 类型、ECMAScript 类和依赖注入都是完全正交的概念。
鉴于 TypeScript 的性质,它只提供设计时类型,这会导致严重的混乱。
有趣的是,Angular 团队设计了他们自己的编程语言,称为 @Script 专门用于 Angular 2 的开发。@Script 是 JavaScript 和 TypeScript 的衍生品,它通过添加某种程度的类型具体化同时避开装饰器来区分自己。然后竞争注释功能。 他们在 2014 年底放弃了这种语言,转而使用 TypeScript。
尽管如此,我有时仍然认为激发@Script 的相同理念仍然影响着 Angular。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.