Reputation: 724
I am a bit stuck with the type hinting in TypeScript when the parameter is class of specific type. I am trying to implement an event system and when I use the code from TypeScript playground, everything works fine for pure JavaScript. However, the standard compilation cause Errors of "TS2693: 'C1' only refers to a type, but is being used as a value here." How can I type-hint this method?
function method
<C1 extends BaseClass, C2 extends BaseClass>
(c1: typeof C1, c2: typeof C2, callback: (arg1: C1, arg2: C2) => void){
// ...
}
Full example:
abstract class BaseClass {}
const dict = {}
function method
<C1 extends BaseClass, C2 extends BaseClass>
(c1: typeof C1, c2: typeof C2, callback: (arg1: C1, arg2: C2) => void){
dict[c1] = dict[c1] || {};
dict[c1][c2] = dict[c1][c2] || [];
dict[c1][c2].push(callback);
}
class MyClass1 extends BaseClass{}
class MyClass2 extends BaseClass{}
method(MyClass1, MyClass2, (arg1: MyClass1, arg2: MyClass2) => {
console.log("Callback");
});
const c1 = new MyClass1();
const c2 = new MyClass2();
dict[MyClass1][MyClass2][0](c1, c2);
Upvotes: 3
Views: 3261
Reputation: 526
Classes in TypeScript don't behave like you think. Check this snippet out, straight from the TS interpreter:
~ ts-node
> class a {}
undefined
> typeof a
'function'
It shows that a
is just a function, so that parameter type hint will evaluate to the literal string 'function'
!
> function b(param: a) { console.log(param) };
> b(a)
[Function: a]
> b(new a())
a {}
The above code is an example of how to properly use class types as parameters. No need for typeof
. In your code it could look something like this:
function method
<C1 extends BaseClass, C2 extends BaseClass>
(c1: C1, c2: C2, callback: (arg1: C1, arg2: C2) => void){
// ...
}
If what you mean is you want to actually pass the class type itself, then you need to work around TS's reflection limitations. You can pass the type as a function that returns a type:
function method
<C1 extends BaseClass, C2 extends BaseClass>
(c1: new () => C1, c2: new () => C2, callback: (arg1: C1, arg2: C2) => void){
new c1() instanceof C1; // true
new c2() instanceof C2 // true
c1 instanceof C1 // false
}
Tada!
Upvotes: 3