打字稿:具有原始类型约束的通用类型

typescript : generic type with primitive types constrain

我在打字稿中有以下通用 classes

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 '(Anonymous class)' 错误地扩展了基础 class 'Column'。 属性 'getValue' 的类型不兼容。 类型 '(value: number) => number' 不可分配给类型 '(value: number) => S'。 类型 'number' 不可分配给类型 'S'

您的 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 带到 class,您的功能可以缩小到 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
    }
}()

On Column getter 和 setter S 不一定是同一类型,因此您应该将类​​型参数移至其父级 class: 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以上的版本。

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