【发布时间】:2021-07-19 10:51:31
【问题描述】:
我正在将我的 react 应用程序转换为 Typescript,但我遇到了 reducer 中操作类型的问题。
我在使用可区分联合时遇到错误,例如在操作 ADD_TO_CART 中,当我在可区分联合中有多个声明时,它会显示错误
Property 'product' does not exist on type 'ICart | IProduct | { products: IProduct[]; } | IOrder'.
Property 'product' does not exist on type 'IProduct'.ts(2339)
当我删除所有其他操作类型并只留下 ADD_TO_CART 时,错误从打字稿中消失了。如何声明我的操作以使其不显示错误?
其他类型也是如此,例如 GET_PRODUCTS 当我从 Discriminate Unions 中删除所有其他类型并且只留下 GET_PRODUCTS 时,错误消失了,但是当我声明它显示的所有操作时:
Property 'products' does not exist on type 'ICart | IProduct | { products: IProduct[]; } | IOrder'.
Property 'products' does not exist on type 'ICart'.ts(2339)
我的类型 - 声明文件
export interface IArticle {
_id: string,
title: string,
shortDescription: string,
content: string,
author: string,
createdAt: Date,
updatedAt: Date,
}
export interface IProduct {
_id: string,
title: string,
category: string,
shortDescription: string,
description: string,
photo: {
fileName: string,
url: string,
},
createdAt: Date,
updatedAt: Date,
}
export interface ICart {
product: IProduct,
qty: number,
}
export interface IOrder {
nr: number,
products: object,
user: string | IUser,
status: string,
comment: string,
createdAt: Date,
updatedAt: Date,
}
我的减速器
import {
ADD_TO_CART, GET_PRODUCTS, DELETE_FROM_CART, ADD_ORDER, GET_ORDERS, GET_ONE_ORDER,
CLEAR_ONE_ORDER, ARCHIVE_ORDER, GET_ARCHIVED_ORDERS, GET_ONE_ARCHIVED_ORDER,
CLEAR_ONE_ARCHIVED_ORDER, GET_ORDERS_ADMIN, START_ORDER, GET_RECAP_ADMIN,
} from '../actions/types.action';
import { IProduct, IOrder, ICart } from '../declarations';
const initialState = {
products: [],
isLoading: true,
cart: {},
orders: [],
adminOrders: [],
recapLoading: true,
recapAdmin: null,
archivedOrders: [],
archivedOrdersLoading: true,
oneArchivedOrder: null,
oneArchivedOrderLoading: true,
cartLength: null,
oneOrder: null,
oneOrderLoading: true,
backdropOpen: false,
};
type ACTIONTYPE =
| { type: 'ADD_TO_CART'; payload: ICart }
| { type: 'GET_PRODUCTS'; payload: { products: IProduct[] } }
| { type: 'DELETE_FROM_CART'; payload: IProduct }
| { type: 'ADD_ORDER'; payload: null }
| { type: 'GET_ORDERS'; payload: null }
| { type: 'GET_ONE_ORDER'; payload: null }
| { type: 'CLEAR_ONE_ORDER'; payload: null }
| { type: 'ARCHIVE_ORDER'; payload: IOrder }
| { type: 'GET_ARCHIVED_ORDERS'; payload: null }
| { type: 'GET_ONE_ARCHIVED_ORDER'; payload: null }
| { type: 'CLEAR_ONE_ARCHIVED_ORDER'; payload: null }
| { type: 'GET_ORDERS_ADMIN'; payload: null }
| { type: 'START_ORDER'; payload: null }
| { type: 'GET_RECAP_ADMIN'; payload: null };
export default function (state = initialState, action: ACTIONTYPE) {
const { type, payload } = action;
switch (type) {
case ADD_TO_CART:
return {
...state,
cart: {
...state.cart,
[payload?.product?._id]: {
product: payload.product,
qty: payload.qty,
},
},
};
case DELETE_FROM_CART:
return {
...state,
cart: update(state.cart, {
$unset: [payload],
}),
};
case GET_PRODUCTS:
return {
...state,
products: payload.products,
isLoading: false,
};
case GET_RECAP_ADMIN:
return {
...state,
recapAdmin: payload,
recapLoading: false,
};
case ADD_ORDER:
return {
...state,
cart: {},
backdropOpen: false,
};
case START_ORDER:
return {
...state,
backdropOpen: true,
};
case GET_ORDERS:
return {
...state,
orders: payload,
isLoading: false,
};
case GET_ONE_ORDER:
return {
...state,
oneOrder: payload,
oneOrderLoading: false,
};
case CLEAR_ONE_ORDER:
return {
...state,
oneOrder: null,
oneOrderLoading: true,
};
case ARCHIVE_ORDER:
return {
...state,
orders: state.orders.filter((o) => o._id !== payload?._id),
isLoading: false,
};
case GET_ARCHIVED_ORDERS:
return {
...state,
archivedOrders: payload,
archivedOrdersLoading: false,
};
case GET_ONE_ARCHIVED_ORDER:
return {
...state,
oneArchivedOrder: payload,
oneArchivedOrderLoading: false,
};
case CLEAR_ONE_ARCHIVED_ORDER:
return {
...state,
oneArchivedOrder: null,
oneArchivedOrderLoading: true,
};
case GET_ORDERS_ADMIN:
return {
...state,
adminOrders: payload,
isLoading: false,
};
default:
return state;
}
}
【问题讨论】:
标签: reactjs typescript redux