Typescript 财产不存在';在联合类型上不存在

Typescript 财产不存在';在联合类型上不存在,typescript,Typescript,我对联合类型有问题: 首先,我定义了两个接口: export interface Action { type: string; export interface ActionWithPayload<T> extends Action { payload: T; } 这是我的问题-编译器complines指出,我的联合类型上不存在属性有效负载(导致此问题的原因是…action.payload): 不知道是bug还是我做错了什么。我认为您在两种操作类型中缺少类型鉴别器字段的字

我对联合类型有问题:

首先,我定义了两个接口:

export interface Action {
  type: string;

export interface ActionWithPayload<T> extends Action {
  payload: T;
}
这是我的问题-编译器complines指出,我的联合类型上不存在属性
有效负载
(导致此问题的原因是
…action.payload
):


不知道是bug还是我做错了什么。

我认为您在两种操作类型中缺少类型鉴别器字段的字符串文字值。您需要使用此选项来切换以区分案例块中的实际类型。有不止一种方法可以做到这一点,但这里有一种方法你可以做到

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 }>;
导出接口操作{
类型:K;
}
导出接口操作WithPayload扩展操作{
有效载荷:T;
}
导出类型LoadDrafts=操作;
导出类型LoadDraftsSuccess=ActionWithPayload;
这使您的类型列成为可在继承接口时指定的通用字符串文字


重要的是,您的类型值必须是字符串文字,而不是字符串,因此您可以得到一组有限的值,而不是无限的字符串可能性。

我不确定这是否是您的问题,“LoadDraftsSuccess”已经扩展了“Action”,从而同时包含了这两个属性。您可能应该删除联合类型,只使用“LoadDraftsSuccess”。我认为您在两种操作类型中缺少类型鉴别器字段的字符串文字值。你需要这个来帮助你的开关辨别箱子里到底是哪种类型。这很有帮助,谢谢。
Action
接口实际上来自
@ngrx/store
包,因此我必须自己编写一个
SuperAction
接口。FWIW您可能不需要显式继承接口。TypeScript在结构上是类型化的,因此如果类型具有包含字符串内容的类型字段,则类型将隐式满足接口。
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;
    }
  }
};
[ts]
Property 'payload' does not exist on type 'DraftsActionsUnion'.
  Property 'payload' does not exist on type 'Action'.
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 }>;