Typescript中的Angular:如何将泛型Type传递给函数
使用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; } 函数中的第一行抛出错误:
这里的语法是什么?我正在调用的Angular函数 – By.directive() – 接受Type< any>类型的参数,并且是documented here 解决方法
角度类型< T>是一个糟糕的API.你是众多因其坦率不负责任的命名而误导的人之一(见评论).的类型< T>真的意思是可构造的.它是您可以使用new调用的值的类型. By.directive取值不是类型.该值的类型是可以使用new调用的东西,可以构造.这意味着一个类或一个函数. 但是,您可以编写您想要的功能. 这是我写它的方式.
function getDirective<T>( hostFixture: ComponentFixture<any>,ComponentConstructor: new (...args: any[]) => T ): T { const debugElement = hostFixture.debugElement.query(By.directive(ComponentConstructor)); return debugElement && debugElement.componentInstance || undefined; } 然后这样称呼它 const instance = getDirective(fixture,MyComponent); 备注: TypeScript类型纯粹是设计时构造.语言的整个类型系统经过精心设计,可以在转换过程中完全擦除,特别是对程序的运行时行为没有影响. 为什么我要说名称Type< T>是不负责任的?因为成千上万的程序员在Angular的上下文中第一次学习TypeScript.通过命名类型Type,他们很容易误解. 这尤其重要,因为类型Type< T>通常归结为一个类的值,很多人已经将类型与TypeScript和vanilla JavaScript中的类混淆了. Angular想要将这些概念混为一谈,它希望JavaScript中的类类似于许多其他语言中的类,但它们根本不是.值得注意的是,我更喜欢的Aurelia这样的框架也鼓励这种混淆,但是,因为它们不会尝试强制使用TypeScript,因为它们允许通过类上的属性指定依赖项(可能具有讽刺意味的是AngularJS,混淆)不太可能.无论如何,TypeScript类型,ECMAScript类和依赖注入都是完全正交的概念. 鉴于TypeScript的性质,它只提供设计时类型,这会导致严重的混淆. 值得注意的是,Angular团队设计了他们自己的编程语言,专门用于开发Angular 2的@Script.@ Script是JavaScript和TypeScript的衍生物,它通过添加某种程度的类型设置来区分自己,同时避开装饰器然后竞争注释功能.他们在2014年末放弃了这种语言,而选择使用TypeScript. 我仍然有时认为启发@Script的相同哲学仍会影响Angular. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |