我在我的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
答案 0 :(得分:1)
如果我执行默认的npm install typescript-fsa typescript-fsa-reducers
,可以给我typescript-fsa@3.0.0-beta-2
和typescript-fsa-reducers@0.4.5
,而后者具有自己的typescript-fsa@2.5.0
副本,则可以重现该问题。推论失败,因为typescript-fsa@3.0.0-beta-2
和typescript-fsa@2.5.0
具有ActionCreator
的不同定义。 (令人尴尬的是,我花了多长时间才意识到这一点!)新定义具有一个条件类型,可以测试Payload extends void
;当Payload
是已知无法分配给void
的具体类型时,新定义将简化为与原来的相似,从而使您的代码可以正常工作,但是当Payload
为类型变量TStartPayload
,不能进行简化。
您不应尝试同时使用两个不兼容的typescript-fsa
版本;编译错误可能只是麻烦的开始。如果要使用typescript-fsa-reducers
,则应将项目切换到与其兼容的typescript-fsa
版本。