case generic type parameters for primitives
Background
I have the following generic class in TypeScript, that accepts a constructor function and a callback as its constructor arguments:
class InputDataPort<T> {
constructor(type: new (...args: any[]) => T, listener?: (data: T) => void);
onUpdate(listener?: (data: T) => void);
// ... lots of other methods depending on the generic type parameter 'T'
}
var dataPortA = new InputDataPort(Array, array => console.log(array)); // T: Array
var dataPortB = new InputDataPort(Date, array => console.log(array)); // T: Date
...
Here, I'm essentially defining the generic type parameter as a constructor argument. The reason it's this way is that I need to know the generic type at runtime, and this approach enables that.
Problem
However, I'm running into a problem with primitive types. Basically, when I do the following:
var dataPortN = new InputDataPort(Number, num => console.log(num));
num
is of type Number
, and the TypeScript compiler does not allow assigning a Number
to a number
(obviously, number
cannot be specified as the argument to type
):
var myNum: number;
// ERROR: 'number' is a primitive, but 'Number' is a wrapper object ...
var dataPortM = new InputDataPort(Number, num => myNum = num);
In this case (as well as in the case of other primitive/wrapper types), I would like to use the corresponding primitive types as the generic type parameter T
.
Essentially, I'm looking for the following type definition:
T
is Number, then number T
is String, then string T
is Boolean, then boolean T
as-is To the best of my knowledge, method overloading is not sufficient here, as it doesn't provide a class-level generic type.
Although I'm not sure if the requirements described in the question are possible at all, one solid workaround is specializing the base InputDataPort
class for each primitive type.
For example, to support number
, one can do:
class InputNumberDataPort extends InputDataPort<number> {
constructor(listener?: (data: number) => void) {
super(Number as any, listener);
}
}
Same for the rest with InputStringDataPort
, InputBooleanDataPort
, and so on. This approach will provide the correct generic types for the TypeScript compiler, and also the correct corresponding constructor references at runtime.
上一篇: Haskell词法布局规则的实现
下一篇: 用于基元的案例泛型类型参数