我遇到了联合类型的问题:
首先,我定义了两个接口:
export interface Action {
type: string;
export interface ActionWithPayload<T> extends Action {
payload: T;
}
接下来,我定义了几种类型和联合类型供以后使用:
export type LoadDrafts = Action;
export type LoadDraftsSuccess = ActionWithPayload<{ [K: string]: Draft }>;
export type DraftsActionsUnion =
| LoadDrafts
| LoadDraftsSuccess;
最后,我在reducer函数中使用了union类型:
export const draftsReducer = (
state = initialState,
action: DraftsActionsUnion
): DraftsState => {
switch (action.type) {
case DraftsActionsTypes.LoadDrafts: {
return {
...state,
loading: true
};
}
case DraftsActionsTypes.LoadDraftsSuccess: {
return {
...state,
loading: false,
loaded: true,
entities: {
...state.entities,
...action.payload
}
};
}
default: {
return state;
}
}
};
还有我的问题 - 编译器认为我的联合类型中不存在属性payload
(...action.payload
导致此问题):
[ts]
Property 'payload' does not exist on type 'DraftsActionsUnion'.
Property 'payload' does not exist on type 'Action'.
Dunno,如果它是一个错误或我做错了什么。
答案 0 :(得分:2)
我认为您在2种动作类型中缺少类型鉴别器字段的字符串文字值。你的开关需要这个来区分case块中实际的类型。有不止一种方法可以做到这一点,但这是你可以做到的一种方式。
export interface Action<K extends string> {
type: K;
}
export interface ActionWithPayload<K, T> extends Action<K> {
payload: T;
}
export type LoadDrafts = Action<‘loadDrafts’>;
export type LoadDraftsSuccess = ActionWithPayload<‘loadDraftSuccess’, { [K: string]: Draft }>;
这使得您的类型列成为可在继承接口时指定的通用字符串文字。
重要的是你的类型值是字符串文字而不是字符串,所以你得到一组有限的值而不是有效的无限字符串可能性。