Typescript中的Angular:如何将泛型Type传递给函数

前端之家收集整理的这篇文章主要介绍了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;
}

函数中的第一行抛出错误

TS2693: ‘T’ only refers to a type,but is being used as a value here

这里的语法是什么?我正在调用的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.

猜你在找的Angularjs相关文章