当“ typescript-fsa-reducers”插入不兼容版本的“ typescript-fsa”

时间:2018-08-26 12:00:36

标签: typescript

我在我的React应用中使用typescript-fsa,并且面临以下行为,我不确定这是typescript限制还是{{1 }}库,或者只是我做错了事。

我具有以下通用功能:

typescript-fsa

使用上述功能,function CreateAPIOperationReducer< TStartPayload >() { const actionCreator = actionCreatorFactory(); const actions = { start: actionCreator<TStartPayload>(`START`) }; } 的类型似乎为actions.start

但是,如果我将(property) start: ActionCreator<TStartPayload> 更改为TStartPayload

string

然后start: actionCreator<string>(`START`) 的类型是:

actions.start

调用(property) start: { (payload: string, meta?: { [key: string]: any; } | null | undefined): Action<string>; type: string; match: (action: AnyAction) => action is Action<string>; }

的预期结果

我的问题是为什么对于通用参数actionCreator,我看不到以下类型的TStartPayload

actions.start

我还发现如果将通用参数包装在接口中,例如:

(property) start: {
(payload: TStartPayload /*<< HERE*/, meta?: {
    [key: string]: any;
} | null | undefined): Action<TStartPayload> /*<< HERE*/;
type: string;
match: (action: AnyAction) => action is Action<TStartPayload> /*<< HERE*/;
}

并输入以下内容:

interface IPayloadContainer<Payload> {
  payload: Payload;
}

然后,如果我使用字符串/数字,则start: actionCreator<IPayloadContainer<TStartPayload>>(`START`) 的类型类似于它的类型,但是这次是start。尽管这行得通,但我想避免这是一个额外的层次,该操作的有效负载是我传递的实际类型,而不是该类型上的容器。

我是IPayloadContainer的新手,所以有可能我遗漏了一些明显的东西。

编辑

Matt McCutchen似乎说要显示的类型与实际类型不同。我使用typescript-fsa-reducers创建减速器,并使用以下代码:

typescript

我确实得到了有效载荷的正确类型。但是,我必须明确告诉import actionCreatorFactory from "typescript-fsa"; import { reducerWithInitialState } from "typescript-fsa-reducers"; function CreateAPIOperationReducer< TStartPayload >() { interface IAPIOperation { pending: boolean; } const initialState: IAPIOperation = { pending: false, }; const actionCreator = actionCreatorFactory(); const actions = { start: actionCreator<TStartPayload>(`START`) }; const reducer = reducerWithInitialState(initialState) .case<TStartPayload /*<< HERE*/>(actions.start, (state, payload /* << payload here is of type TStartPayload */) => { return Object.assign({}, state, initialState, { pending: true }); }) return { reducer, actions, initialState }; } 函数的有效载荷类型,否则它将认为有效载荷的类型为case。例如,如果我的有效负载类型是{},则无需告诉string类型,它就可以从动作创建者那里推断出来。所以我认为这就是我困惑的地方。

另外,如果我使用case中的本机isType函数而不是使用typescript-fsa,则可以正确推断出有效载荷:

typescript-fsa-reducers

1 个答案:

答案 0 :(得分:1)

如果我执行默认的npm install typescript-fsa typescript-fsa-reducers,可以给我typescript-fsa@3.0.0-beta-2typescript-fsa-reducers@0.4.5,而后者具有自己的typescript-fsa@2.5.0副本,则可以重现该问题。推论失败,因为typescript-fsa@3.0.0-beta-2typescript-fsa@2.5.0具有ActionCreator的不同定义。 (令人尴尬的是,我花了多长时间才意识到这一点!)新定义具有一个条件类型,可以测试Payload extends void;当Payload是已知无法分配给void的具体类型时,新定义将简化为与原来的相似,从而使您的代码可以正常工作,但是当Payload为类型变量TStartPayload,不能进行简化。

您不应尝试同时使用两个不兼容的typescript-fsa版本;编译错误可能只是麻烦的开始。如果要使用typescript-fsa-reducers,则应将项目切换到与其兼容的typescript-fsa版本。