首页 文章

基元的特殊情况泛型类型参数

提问于
修改于
浏览 1853
1

背景

我在TypeScript中有以下泛型类,它接受构造函数和回调作为其构造函数参数:

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
...

在这里,我基本上将泛型类型参数定义为构造函数参数 . 这种方式的原因是我需要在运行时知道泛型类型,这种方法可以实现 .

问题

但是,我遇到了原始类型的问题 . 基本上,当我做以下事情时:

var dataPortN = new InputDataPort(Number, num => console.log(num));

num 的类型为 Number ,TypeScript编译器不允许将 Number 分配给 number (显然, number 不能指定为 type 的参数):

var myNum: number;

// ERROR: 'number' is a primitive, but 'Number' is a wrapper object ...
var dataPortM = new InputDataPort(Number, num => myNum = num);

在这种情况下(以及其他原始/包装类型的情况),我想使用相应的基元类型作为泛型类型参数 T .

Essentially, I'm looking for the following type definition:

  • 如果 T 是数字,那么数字

  • 如果 T 是String,则为else,然后是字符串

  • 否则,如果 T 是布尔值,则为布尔值

  • 其他 T 原样

据我所知,方法重载在这里是不够的,因为它不提供类级泛型类型 .

1 回答

  • 0

    虽然我不确定问题中描述的要求是否可行,但一个可靠的解决方法是为每种基本类型专门化基础 InputDataPort 类 .

    例如,要支持 number ,可以执行以下操作:

    class InputNumberDataPort extends InputDataPort<number> {
        constructor(listener?: (data: number) => void) {
            super(Number as any, listener);
        }
    }
    

    其余部分与 InputStringDataPortInputBooleanDataPort 相同,依此类推 . 此方法将为TypeScript编译器提供正确的泛型类型,并在运行时提供正确的相应构造函数引用 .

相关问题