2017-09-24 144 views
0

我有以下的一般类的打字稿打字稿:泛型类型基本类型约束

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

,但我不知道为什么得到这个错误类“(匿名类)”不正确地扩展基类“列”。 属性'getValue'的类型不兼容。 类型'(value:number)=> number'不能分配给type'(value:number)=> S'。 类型“数”是不能分配给输入“S”

+0

可能是您必须以具体的方式定义S. S扩展布尔值,但是它真的是什么? – jaibatrik

+0

@jaibatrik我编辑我的问题也许它现在更清楚,我希望ts编译器推断值类型** ColumnValue类**并确保它是** Primative类型** –

回答

1

Column getter和setter S不一定是同一类型的,所以你应该在Param类型移动到它的父类:Column<T, S extends Primative>

type UserId = number 
type Primative = string | number | boolean 
class ColumnValue<T, S extends Primative> { 
    constructor(public columnName: String, public value: S) { } 
} 
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, number> { 
    constructor() { super("id") } 
    public getValue(value: UserId): number { 
     return value 
    } 
}() 

以上版本至少为has no errors

我明白,你可能要推断从S任何类型你与你设定装置使用,但Column必须在实例化一个明确的类型,这样就意味着你要么明确当调用构造函数(即new Column<UserId, number>(...))或在构造函数中添加一个S参数,以便可以从中推断出S(如new Column<UserId>('id', 123)

+0

谢谢,但它是一个编译器错误,或推断'S'有一个逻辑意义 –

1

getValue使用通用S,因此,继承的实现必须使用S为好。

如果拿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 
    } 
}()