我在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;
答案 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)
中)