代码之家  ›  专栏  ›  技术社区  ›  Abdo Salah

typescript:带有基元类型约束的泛型类型

  •  4
  • Abdo Salah  · 技术社区  · 7 年前

    我在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
        }
    }()
    

    但我不知道为什么会出现这个错误 类“(匿名类)”错误地扩展了基类“列”。 属性“getValue”的类型不兼容。 类型'(值:数字)=>数字“不可分配给类型”(值:数字)=>S’。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Leo Haim Evgi    6 年前

    在…上 Column S 不一定是同一类型,因此应将类型param移动到其父类: 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,但是 实例化时必须具有定义良好的类型,因此这意味着您在调用构造函数(即 new Column<UserId, number>(...) S 可以从中推断(如 new Column<UserId>('id', 123) )

        2
  •  1
  •   Rodris    7 年前

    getValue 使用泛型 S 因此,继承的实现必须使用

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

    如果你接受 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
        }
    }()