I'm still having a hard time with the type checking system of TypeScript. Suppose a composite that holds a collection of elements which all derive from a common base class. How can I implement a function that recursively goes up the hierarchy and returns the first anchestor of a given type?
abstract class Employee
{
public Superior: Employee;
/** THIS IS NOT WORKING */
public getSuperiorOfType<T extends Employee>( type: typeof T ): T
{
if (this instanceof T) return this;
else if (this.Superior !== undefined) return this.getSuperiorOfType(type);
}
}
class Manager extends Employee {}
class TeamLead extends Employee {}
class Developer extends Employee {}
let tom = new Manager();
let suzanne = new TeamLead();
let ben = new Developer();
ben.Superior = suzanne;
suzanne.Superior = tom;
let x = ben.getSuperiorOfType( Manager ); // x = tom
Thanks in advance for any help...
The type of 'class type' can not be declared as typeof T
. typeof
in type position is applicable only to variables, not types. You need to use so-called constructor signature for that:
public getSuperiorOfType<T extends Employee>(type: { new(...args: any[]): T}): T
You can't check if an object is instanceof
of a generic type parameter - instanceof T
does not work because generic type parameters do not exist at runtime. But you have type
as actual function parameter, so instanceof type
should work.
There is no real recursion in your code - you are always calling getSuperiorOfType
for the same this
object. You need to call it as this.Superior.getSuperiorOfType(...)
to move up one step in hierarchy.
abstract class Employee
{
public Superior: Employee;
public getSuperiorOfType<T extends Employee>(type: { new(...args: any[]): T}): T
{
if (this instanceof type) return this;
else if (this.Superior !== undefined) return this.Superior.getSuperiorOfType(type);
}
}
class Manager extends Employee {}
class TeamLead extends Employee {}
class Developer extends Employee {}
let tom = new Manager();
let suzanne = new TeamLead();
let ben = new Developer();
ben.Superior = suzanne;
suzanne.Superior = tom;
let x = ben.getSuperiorOfType(Manager);
console.log(x === tom); // true