typescript:具有原始类型约束的泛型类型

时间:2017-09-24 06:07:14

标签: typescript typescript-generics

我在typescript

中有以下泛型类
type UserId = number
type Primitive = string | number | boolean
class ColumnValue<T, S extends Primitive> {
    constructor(public columnName: String, public value: S) { }
}
abstract class Column<T> {
    constructor(public columnName: String) { }
    public set<S extends Primitive>(value: T): ColumnValue<T, S> {
        return new ColumnValue(this.columnName, this.getValue(value))
    }
    public abstract getValue<S extends Primitive>(value: T): S
}
let id = new class extends Column<UserId> {
    constructor() { super("id") }
    public getValue(value: UserId): number {
        return value
    }
}()

但我不知道为什么会出现此错误 Class&#39;(Anonymous class)&#39;错误地扩展基类&#39;列&#39;。   财产类型&#39; getValue&#39;是不相容的。     输入&#39;(值:数字)=&gt;数&#39;不能分配给&#39;(值:数字)=&gt; S&#39 ;.       输入&#39;数字&#39;不能分配给&#39;

2 个答案:

答案 0 :(得分:1)

您的getValue使用通用S,因此,继承的实现也必须使用S

let id = new class extends Column<UserId> {
    constructor() { super("id") }
    public getValue<S extends Primative>(value: UserId): S {
        return <S>value
    }
}()

如果你将S带到课堂上,你的功能可以缩小到number

abstract class Column<T, S extends Primative> {
    constructor(public columnName: String) { }
    public set(value: T): ColumnValue<T, S> {
        return new ColumnValue(this.columnName, this.getValue(value))
    }
    public abstract getValue(value: T): S
}

let id = new class extends Column<UserId, UserId> {
    constructor() { super("id") }
    public getValue(value: UserId): number {
        return value
    }
}()

答案 1 :(得分:1)

Column上,getter和setter S不一定是同一类型,因此您应该将类​​型参数移动到其父类:Column<T, S extends Primitive>

type UserId = number
type Primitive = string | number | boolean
class ColumnValue<T, S extends Primitive> {
    constructor(public columnName: String, public value: S) { }
}
abstract class Column<T, S extends Primitive> {
    constructor(public columnName: String) { }
    public set(value: T): ColumnValue<T, S> {
        return new ColumnValue(this.columnName, this.getValue(value))
    }
    public abstract getValue(value: T): S
}
let id = new class extends Column<UserId, number> {
    constructor() { super("id") }
    public getValue(value: UserId): number {
        return value
    }
}()

至少has no errors以上的版本。

我知道您可能希望从您使用setter的任何类型推断S,但Column在实例化时必须具有明确定义的类型,这意味着您在调用时要么显式构造函数(即new Column<UserId, number>(...))或在构造函数中添加S参数,以便可以从中推断出S(如在new Column<UserId>('id', 123)中)