Typescript opposite / reverse operation of "typeof"

1.9k Views Asked by At

Angular can Query subComponents by Types, which is used in Testing like this:

fixture.debugElement.query( By.directive( ComponentType ) );

Now i wanted to make a function which does this for me:

import { ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Type } from '@angular/core';

export function findSubComponent<T>( fixture: ComponentFixture<any>, componentType: T & Type<any> ): T {
  const subComponentDebugElement = fixture.debugElement.query( By.directive( componentType ) );
  return subComponentDebugElement.componentInstance;
}

Now here comes the problem. My function currently returns typeof ComponentType instead of an actual object of ComponentType and therefore i can not access its properties.

The Type of subComponentDebugElement.componentInstance here is any, so i can just declare the type in the return Type argument (function (): T)

How can i turn T which stands for typeof ComponentInstance in this case into ComponentInstance?

2

There are 2 best solutions below

0
Jeremias Nater On BEST ANSWER

InstanceType<T>

As suggested by @jcalz the solution to this was to use InstanceType<T> like this:

type AbstractClassType = abstract new ( ...args: any ) => any;

export function querySubComponent<T extends AbstractClassType>(...): InstanceType<T> {
...
}

use of the AbstractClassType as abstract new ( ...args: any ) => any

Please note that the AbstractClassType might not be needed with your existing type definition, but apparently the generic InstanceType<> needs to use a type with a constructor, otherwise i get the following TS-Error: Type 'T' does not satisfy the constraint 'abstract new (...args: any) => any'.

0
user3413723 On

Basically the same answer, but more compact

function querySubComponent<T extends abstract new (...args: any) => any>(fixture: ComponentFixture<any>, componentType: T & Type<any>) {
    const subComponentDebugElement = fixture.debugElement.query( By.directive( componentType ) );
    return subComponentDebugElement.componentInstance as InstanceType<T>;
}