2017-08-31 60 views
0

我得到了打字稿2.4.2錯誤在通用類與約束不是與較爲寬鬆的接口兼容。我得到以下錯誤:打字稿通用與約束是不能分配給通用接口

ts/components/Schedule.ts(37,13): error TS2322: Type '{ personWeekView: PlanItemScheduleView; projectWeekView: PlanItemScheduleView; r...' is not assignable to type 'Map'. Property 'personWeekView' is incompatible with index signature. Type 'PlanItemScheduleView' is not assignable to type 'IPlanItemScheduleView'. Types of property 'onAddedItem' are incompatible. Type '(item: T, initial: boolean) => void' is not assignable to type '(item: T, initial: boolean) => void'. Types of parameters 'item' and 'item' are incompatible. Type 'T' is not assignable to type 'PlanItem'.

ts/views/PlanItemScheduleView.ts(2,18): error TS2420: Class 'PlanItemScheduleView' incorrectly implements interface 'IPlanItemScheduleView'. Types of property 'onAddedItem' are incompatible. Type '(item: T, initial: boolean) => void' is not assignable to type '(item: T, initial: boolean) => void'. Types of parameters 'item' and 'item' are incompatible. Type 'T' is not assignable to type 'PlanItem'.

ts/views/PlanItemScheduleView.ts(99,79): error TS2345: Argument of type 'this' is not assignable to parameter of type 'IControllerListener'. Type 'PlanItemScheduleView' is not assignable to type 'IControllerListener'. Types of property 'onAddedItem' are incompatible. Type '(item: T, initial: boolean) => void' is not assignable to type '(item: T, initial: boolean) => void'. Types of parameters 'item' and 'item' are incompatible. Type 'T' is not assignable to type 'PlanItem'.

接口

namespace Planning { 
    export interface IPlanItemScheduleView extends IView, IControllerListener<IPlanItem> { 
     setTimespan(timespan: Timespan): void; 
     getName(): string; 
    } 
} 
namespace Planning { 
    export interface IControllerListener<T> { 
    /** 
    * Notifies the listener that an item is added to the cache so it can add it to its view. 
    * 
    * @template T 
    * @param {T} item 
    * @param {boolean} initial 
    * 
    * @memberOf IControllerListener 
    */ 
    onAddedItem<T>(item: T, initial: boolean): void; 
    } 
} 

namespace Planning { 
    export class PlanItemScheduleView<T extends PlanItem> implements IPlanItemScheduleView { 

     public onAddedItem<T extends PlanItem>(item: T, initial: boolean): void { 
      // implementation that needs properties on PlanItem 
     } 
    } 
} 

PlanItem是由幾個實際實現繼承的抽象基類。我有幾個不同類型的viwes的,我構建這樣的:

// Create the different views 
    this._views = { 
      personWeekView: new PlanItemScheduleView<Person>(this._options, this._logger, this), 
      projectWeekView: new PlanItemScheduleView<Project>(this._options, this._logger, this), 
      resourceWeekView: new PlanItemScheduleView<Resource>(this._options, this._logger, this), 
     }; 

我想我在TSC的其他版本之前有這個編譯但我可能是錯誤的。我怎樣才能解決這個問題?

回答

1

您不需要onAddedItem上的通用參數,如果您希望onAddedItem採用與該類相同的參數類型,則可以使用class參數。你可以做IPlanItemScheduleView通用的,這樣下來傳遞PlanItemScheduleView類型參數IControllerListener

export interface IControllerListener<T> { 
    onAddedItem(item: T, initial: boolean): void; 
} 
export interface IPlanItemScheduleView<T extends IPlanItem> extends IControllerListener <T> { 

} 
export class PlanItemScheduleView<T extends PlanItem> implements IPlanItemScheduleView<T> { 
    public onAddedItem(item: T, initial: boolean): void { 
     // implementation that needs properties on PlanItem 
    } 
} 

注:編輯考慮到的反饋。

+0

這使得onAddedItem不太安全的,因爲你的建議我可以給onAddedItem提供不同來源的類型,而不是縮小它下降到僅在施工時間,這實際上是使用通用/模板類的原因提供了一個類型的。 – Huupke

+0

您的版本不限制比傳遞給類類型的更多類型。你是說,你想onAddedItem接受PlanItem派生的類型,但不PlanItem本身 –

+0

是,在personWeekView實例的情況下,我想只有一個人是參數的類型,而不是任何其他派生PlanItem類型。 – Huupke