2015-05-18 38 views
0

我有一個功能wrap可以採取TWrapped<T>並返回Wrapped<T>TypeScript 1.4:使用類型聯合

宣佈在TS 1.0:現在

wrap<T>(value: Wrapped<T>, defaultValue?: T): Wrapped<T>; 
wrap<T>(value: T, defaultValue?: T): Wrapped<T>; 

在1.4,我想用union類型來定義的概念, 「無論是TWrapped<T>

class Bar { 
    thing: Wrapped<number>; 
    constructor(thing: number | Wrapped<number>) { 
     this.thing = wrap(thing); 
    } 
} 

但類型檢查this.thing錯誤與:

類型包裝<號碼包裹<號碼>>不可分配包裝<號碼>

類型'number |裹<號>」是不能分配給類型號

我明白,錯誤是,我傳遞給wrapnumber | Wrapped<number>wrap只知道如何處理numberWrapped<number>;

所以我第一次嘗試去宣佈它可以處理T | Wrapped<T>;

wrap<T>(value: T | Wrapped<T>, defaultValue?: T): Wrapped<T>; 
wrap<T>(value: Wrapped<T>, defaultValue?: T): Wrapped<T>; 
wrap<T>(value: T, defaultValue?: T): Wrapped<T>; 

但類型檢查仍然錯誤。如果我右鍵單擊並進入定義,我會看到它仍然綁定到列表中的第三個定義,而不是我先前的更高優先級簽名T | Wrapped<T>

這是預期的行爲?

我應該用類型警衛來解決這本手冊嗎?如果是這樣,有人可以告訴我如何使用這個通用包裝,我有?如何從我的thing變量中獲取類型參數?

回答

1

這編譯:

interface Wrapped<T> { value: T } 
declare function wrap<T>(value: T|Wrapped<T>, defaultValue?: T): Wrapped<T>; 

class Bar { 
    thing: Wrapped<number>; 
    constructor(thing: number | Wrapped<number>) { 
     this.thing = wrap(thing); // No error 
    } 
} 

的聯合類型和兩個重載的功能之間進行選擇的一般指導原則是:如果你可以寫爲單簽名聯合類型,你應該

+0

所以答案是:刪除舊的簽名和允許新的簽名做雙方的工作。涼。我希望能有這樣簡單的東西。再次感謝瑞恩! (你在平局中速度很快)。 – masonk

1

簡單地將重載函數:

class Wrapped<T> { 

    private _value: T; 
    get value(): T { return this._value; } 

    constructor(value: T) { 
     this._value = value; 
    } 
} 

class WrappHelper { 

    public static wrap<T>(value: Wrapped<T> | T, defaultValue ?: T): Wrapped<T> { 
     if (value instanceof Wrapped) 
      return value; 
     else 
      return new Wrapped<T>(<T>value); 
    } 
} 

var a = new Wrapped(100); 
var b = 200; 

var a1: Wrapped<number> = WrappHelper.wrap(a); 
var a2: Wrapped<number> = WrappHelper.wrap(b); 
相關問題