Angular's Type<T> is a bad API. You are one of many who has been mislead by its frankly irresponsible naming (see remarks). 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.
However, you can write the function you wish to.
Here is how I would write it.
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;
}
Then call it like this
const instance = getDirective(fixture, MyComponent);
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 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.
This is especially significant because the type 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.
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. It's worth noting that frameworks such as Aurelia, which I prefer, also encourage this conflating but, since they do not attempt to mandate TypeScript and as they allow dependencies to be specified via a property on classes (perhaps ironically in the manner or AngularJS, confusion is less likely. Irregardless, TypeScript types, ECMAScript classes, and dependency injection are entirely orthogonal concepts.
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.
Type<T>is a bad API. You are one of many who has been mislead by its frankly irresponsible naming.Type<T>really meansConstructable<T>. It is the type of a value that you can call withnewT?