2017-09-24 205 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 
    } 
}()