Typescript中的Angular:如何将泛型类型传递给函数 [英] Angular in Typescript: how to pass generic Type to function
问题描述
使用Typescript编写Angular 5单元测试,我有一个函数将查询DOM并返回 MyComponent
类的实例(如果找到):
pre $函数getMyComponent(hostFixture:ComponentFixture< any>):MyComponent {
const debugElement = hostFixture.debugElement.query(By.directive为MyComponent));
return(debugElement&&&debugElement.componentInstance)||空值;
}
这完美无瑕。现在我想概括一下这个函数,以便它可以根据需要查询任何类型。我认为这可以通过泛型类型来完成,函数的调用方式如下所示:
const实例:MyComponent = getDirective< MyComponent>(夹具);
虽然我无法使用它,这里是破碎的函数:
pre $ function getDirective< T>(hostFixture:ComponentFixture< any>):T {
const debugElement = hostFixture.debugElement.query(By.directive(T));
return(debugElement&&&debugElement.componentInstance)||空值;
函数内的第一行会抛出错误:
TS2693:'T'仅指一种类型,但在这里用作值
这里的正确语法是什么?我调用的Angular函数 - By.directive()
- 接受一个类型的参数< any>
,记录在这里
类型< T>
确实意味着可构造。这是您可以通过 new
调用的值的类型。 By。指令
取得值不是类型。该值的类型是可以用 new
调用的东西,可以构造的东西。这意味着一个类或函数。
然而,您可以写出您想要的函数。
$
pre $
function getDirective< T>(
hostFixture: ComponentFixture< any> ;,
ComponentConstructor:new(... args:any [])=> T
):T {
const debugElement = hostFixture.debugElement.query(By.directive (ComponentConstructor));
返回debugElement&& debugElement.componentInstance ||不确定的;
}
然后像这样称呼
const instance = getDirective(fixture,MyComponent);
备注: 为什么我说这个名字 这是特别重要的,因为类型 Angular希望这些概念这是希望 JavaScript中的类是类似于许多其他语言的类型,但它们根本就不是。 鉴于性质的TypeScript,它只提供设计时间类型,这会导致严重的混淆。 有趣的是,Angular团队设计了自己的编程语言,专门称为@Script用于Angular 2的开发。@Script是JavaScript和TypeScript的衍生产品,它通过添加某种程度的类型实例来避免使用装饰器 Annotations 特性。他们在2014年晚些时候放弃了这种语言,而选择使用TypeScript。 不过,我仍然认为,启发@Script的理念仍然影响Angular。 b $ b Using Typescript to write an Angular 5 unit tests, I have a function that will query the DOM and return an instance of the This works flawlessly. Now I'd like to generalize the function so that it could query any Type on demand. I figured this could be done with generic typesThe function would be called like so: I can't get it working though; Here is the broken function: The first line within the function throws the error: TS2693: 'T' only refers to a type, but is being used as a value here What is the right syntax here? The Angular function I'm calling -- Angular's However, you can write the function you wish to. Here is how I would write it. Then call it like this Remarks: TypeScript types are purely design time constructs. The language's entire type system was carefully designed to be fully erased during transpilation and in particular to have no impact on the runtime behavior of programs. Why do I say that the name This is especially significant because the type Angular wants these concepts to be conflated, it wishes that classes in JavaScript were types like they are in many other languages but they simply are not. Given the nature of TypeScript, which provides design time only types, this leads to serious confusion. It is interesting to note that the Angular team designed their own programming language, called @Script specifically for the development of Angular 2. @Script was a derivative of JavaScript and TypeScript that distinguished itself by adding some degree of type reification while eschewing Decorators for a then competing Annotations feature. They abandoned this language late in 2014, opting to use TypeScript instead. Still I sometimes think that the same philosophy that inspired @Script still influences Angular. 这篇关于Typescript中的Angular:如何将泛型类型传递给函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
TypeScript类型纯粹是设计时间结构。该语言的整个类型系统经过精心设计,在转换过程中完全擦除,特别是对程序的运行时行为没有影响。
类型< T>
是不负责任的?因为成千上万的程序员在Angular的背景下第一次学习TypeScript。通过命名Type类型,他们使事情变得很容易被误解。
Type< T> 通常被认为是一个类的值,很多人已经在TypeScript和vanilla JavaScript中混淆了类的类型。
MyComponent
class if found: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;
}
By.directive()
-- takes an argument of type Type<any>
, and is documented hereType<T>
is a bad API. You are one of many who has been mislead by its frankly irresponsible naming*. Type<T>
really means Constructable. It is the type of a value that you can call with new
.By.directive
takes a value not a type. The type of that value is something which can be called with new
, something that can be constructed. This means a class or a function.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);
Type<T>
is irresponsible? Because thousands of programmers are learning TypeScript for the first time in the context of Angular. By naming a type Type, they have made things very easy to misunderstand.Type<T>
is usually ascribed to a value that is a class and many people already confuse types with classes in TypeScript and in vanilla JavaScript as well.