2017-07-25 17 views
1

一般的な推論の変更により、既存のTypeScriptコードブレークが発生しています。TypeScript 2.4コンパイルエラーを引き起こす一般的な推論

例:

interface Action { 
    type: string; 
} 
interface MyAction extends Action { 
    payload: string; 
} 
interface MyState {} 

type Reducer<S> = <A extends Action>(state: S, action: A) => S; 

const myReducer: Reducer<MyState> = (state: MyState, action: MyAction) => { 
    if (action.type === "MyActionType") { 
     return {}; 
    } 
    else { 
     return {}; 
    } 
}; 

とコンパイルエラー:

Error:(11, 7) TS2322:Type '(state: MyState, action: MyAction) => {}' is not assignable to type 'Reducer<MyState>'. 
    Types of parameters 'action' and 'action' are incompatible. 
    Type 'A' is not assignable to type 'MyAction'. 
     Type 'Action' is not assignable to type 'MyAction'. 
     Property 'payload' is missing in type 'Action'. 

答えて

1
interface MyOtherAction { 
    type: 'MyOtherActionType' 
    foo: number 
} 

declare const state: State 
declare const myOtherAction: MyOtherAction 

// the following is a valid call according to myReducer's signature 
myReducer(state, myOtherAction) 

あなたはmyReducerに割り当てた値を使用すると、エラーが出るので、アクションのすべてのタイプを受け入れませんが。

2つのパラメータ/戻り値の間に制約を作成しないので、2番目のパラメータを汎用化する理由はありません。ここに来て誰にも

type Reducer<S> = (state: S, action: Action) => S; 
+2

注を行う活字体が二変などの非ジェネリック非関数のパラメータを扱うためだけで、これはのみ動作します([議論]を参照してください(https://github.com/Microsoft/TypeScript/issues/14973 ))。 'myReducer()'が 'action'パラメータが' MyAction'型であると仮定することはまだ安全ではありません。安全のためには、myReducerの2番目のパラメータを 'Action'とタイプするか、' Reducer'タイプを 'Type Reducer (状態:S、アクション:A )=> S; 'と' myReducer'は 'Reducer '型になります。 – jcalz

+0

@jcalzそれでは、私は単純な減速機でやってしまったのですが、Reduxに付属しているタイピングではうまくいきません。これはRedux型で修正されたことに言及する価値があります。そこでは、インデックスシグネチャを持つAnyActionという拡張Action型を追加しました: '[index:string]:any'。編集:Reduxタイプ、つまりActionCreator、Dispatch、Storeなどを更新して、この制約付きリデューサーの例を可能にすれば、それはきれいです。 – Ngz

関連する問題