Reactjs 如何为redux操作生成器编写操作?

Reactjs 如何为redux操作生成器编写操作?,reactjs,typescript,redux,Reactjs,Typescript,Redux,这些就是行动 export const fetchProductsStart = () => ({ type: ProductListActionTypes.PRODUCT_LIST_START, }); export const fetchProductSuccess = (products: IProduct) => ({ type: ProductListActionTypes.PRODUCT_LIST_SUCCESS, payload: products, })

这些就是行动

export const fetchProductsStart = () => ({
  type: ProductListActionTypes.PRODUCT_LIST_START,
});

export const fetchProductSuccess = (products: IProduct) => ({
  type: ProductListActionTypes.PRODUCT_LIST_SUCCESS,
  payload: products,
});

export const fetchProductFailure = (error: any) => ({
  type: ProductListActionTypes.PRODUCT_LIST_FAILURE,
  payload: error,
});
我写了这样的动作:

export type Action =
  | ReturnType<typeof fetchProductsStart>
  | ReturnType<typeof fetchProductSuccess>
  | ReturnType<typeof fetchProductFailure>;

我收到了关于
操作的警告。有效负载
。它表示“类型Action上不存在属性'payload'”

并非
Action
联合中的每个分支都有
payload
键,并且编译器不知道采取哪个分支,由于操作的
类型
被扩展为仅
字符串
,而不是
“产品列表(u开始)|“产品列表)成功”|“产品列表(u失败)”

如果您查看
操作的类型,它是

type Action = {
    type: string;
} | {
    type: string;
    payload: IProduct;
} | {
    type: string;
    payload: any;
}
这是因为
ProductListActionTypes
被推断为

const ProductListActionTypes: {
    PRODUCT_LIST_START: string;
    PRODUCT_LIST_SUCCESS: string;
    PRODUCT_LIST_FAILURE: string;
}
const ProductListActionTypes: {
  readonly PRODUCT_LIST_START: "PRODUCT_LIST_START";
  readonly PRODUCT_LIST_SUCCESS: "PRODUCT_LIST_SUCCESS";
  readonly PRODUCT_LIST_FAILURE: "PRODUCT_LIST_FAILURE";
}
然后,编译器无法确定所需的
操作
联合的哪个分支,也无法区分它是哪个操作类型,因为该类型已扩展为
字符串

您可以通过在
ProductListActionTypes
声明的末尾添加
as const
来解决此问题

export const ProductListActionTypes = {
  PRODUCT_LIST_START: 'PRODUCT_LIST_START',
  PRODUCT_LIST_SUCCESS: 'PRODUCT_LIST_SUCCESS',
  PRODUCT_LIST_FAILURE: 'PRODUCT_LIST_FAILURE'
} as const;
然后将
ProductListActionTypes
的类型推断为

const ProductListActionTypes: {
    PRODUCT_LIST_START: string;
    PRODUCT_LIST_SUCCESS: string;
    PRODUCT_LIST_FAILURE: string;
}
const ProductListActionTypes: {
  readonly PRODUCT_LIST_START: "PRODUCT_LIST_START";
  readonly PRODUCT_LIST_SUCCESS: "PRODUCT_LIST_SUCCESS";
  readonly PRODUCT_LIST_FAILURE: "PRODUCT_LIST_FAILURE";
}
然后执行
操作

type Action = {
    type: "PRODUCT_LIST_START";
} | {
    type: "PRODUCT_LIST_SUCCESS";
    payload: IProduct;
} | {
    type: "PRODUCT_LIST_FAILURE";
    payload: any;
}

现在,当您为
操作
联合指定一种操作类型时,编译器知道该联合的哪个分支。

不是
操作
联合中的每个分支都有一个
有效负载
键,编译器也不知道该采取哪个分支,由于操作的
类型
被扩展为仅
字符串
,而不是
“产品列表(u开始)|“产品列表)成功”|“产品列表(u失败)”

如果您查看
操作的类型,它是

type Action = {
    type: string;
} | {
    type: string;
    payload: IProduct;
} | {
    type: string;
    payload: any;
}
这是因为
ProductListActionTypes
被推断为

const ProductListActionTypes: {
    PRODUCT_LIST_START: string;
    PRODUCT_LIST_SUCCESS: string;
    PRODUCT_LIST_FAILURE: string;
}
const ProductListActionTypes: {
  readonly PRODUCT_LIST_START: "PRODUCT_LIST_START";
  readonly PRODUCT_LIST_SUCCESS: "PRODUCT_LIST_SUCCESS";
  readonly PRODUCT_LIST_FAILURE: "PRODUCT_LIST_FAILURE";
}
然后,编译器无法确定所需的
操作
联合的哪个分支,也无法区分它是哪个操作类型,因为该类型已扩展为
字符串

您可以通过在
ProductListActionTypes
声明的末尾添加
as const
来解决此问题

export const ProductListActionTypes = {
  PRODUCT_LIST_START: 'PRODUCT_LIST_START',
  PRODUCT_LIST_SUCCESS: 'PRODUCT_LIST_SUCCESS',
  PRODUCT_LIST_FAILURE: 'PRODUCT_LIST_FAILURE'
} as const;
然后将
ProductListActionTypes
的类型推断为

const ProductListActionTypes: {
    PRODUCT_LIST_START: string;
    PRODUCT_LIST_SUCCESS: string;
    PRODUCT_LIST_FAILURE: string;
}
const ProductListActionTypes: {
  readonly PRODUCT_LIST_START: "PRODUCT_LIST_START";
  readonly PRODUCT_LIST_SUCCESS: "PRODUCT_LIST_SUCCESS";
  readonly PRODUCT_LIST_FAILURE: "PRODUCT_LIST_FAILURE";
}
然后执行
操作

type Action = {
    type: "PRODUCT_LIST_START";
} | {
    type: "PRODUCT_LIST_SUCCESS";
    payload: IProduct;
} | {
    type: "PRODUCT_LIST_FAILURE";
    payload: any;
}

现在,当您为
操作
联合指定一种操作类型时,编译器就知道了该联合的哪个分支。

看起来您想要利用它。但Typescript假定操作的类型为:

类型操作={
类型:字符串;
} | {
类型:字符串;
有效载荷:任何;
} | {
类型:字符串;
有效载荷:任何;
}
因此,它无法区分
switch
语句中的类型。如果我们可以显示
类型
将是
“产品列表(u开始)”;“产品列表(u成功)”;“产品列表(u失败)”
,那么这里有什么帮助呢。如果我们可以告诉Typescript,我们的
ProductListActionTypes
将保持不变,即我们需要修改此对象

我们可以这样做:

export type Action =
  | ReturnType<typeof fetchProductsStart>
  | ReturnType<typeof fetchProductSuccess>
  | ReturnType<typeof fetchProductFailure>;
const ProductListActionTypes={
产品列表开始:“产品列表开始”,
产品列表成功:“产品列表成功”,
产品列表失败:“产品列表失败”,
}作为常量;
现在我们的
Action
类型如下所示:

export type Action =
  | ReturnType<typeof fetchProductsStart>
  | ReturnType<typeof fetchProductSuccess>
  | ReturnType<typeof fetchProductFailure>;
类型操作={
类型:“产品列表开始”;
} | {
类型:“产品列表成功”;
有效载荷:任何;
} | {
类型:“产品列表故障”;
有效载荷:任何;
}
而且,你看不到波浪线


您似乎想利用。但Typescript假定操作的类型为:

类型操作={
类型:字符串;
} | {
类型:字符串;
有效载荷:任何;
} | {
类型:字符串;
有效载荷:任何;
}
因此,它无法区分
switch
语句中的类型。如果我们可以显示
类型
将是
“产品列表(u开始)”;“产品列表(u成功)”;“产品列表(u失败)”
,那么这里有什么帮助呢。如果我们可以告诉Typescript,我们的
ProductListActionTypes
将保持不变,即我们需要修改此对象

我们可以这样做:

export type Action =
  | ReturnType<typeof fetchProductsStart>
  | ReturnType<typeof fetchProductSuccess>
  | ReturnType<typeof fetchProductFailure>;
const ProductListActionTypes={
产品列表开始:“产品列表开始”,
产品列表成功:“产品列表成功”,
产品列表失败:“产品列表失败”,
}作为常量;
现在我们的
Action
类型如下所示:

export type Action =
  | ReturnType<typeof fetchProductsStart>
  | ReturnType<typeof fetchProductSuccess>
  | ReturnType<typeof fetchProductFailure>;
类型操作={
类型:“产品列表开始”;
} | {
类型:“产品列表成功”;
有效载荷:任何;
} | {
类型:“产品列表故障”;
有效载荷:任何;
}
而且,你看不到波浪线