【发布时间】:2020-04-11 03:58:20
【问题描述】:
已解决:如果您遇到这个确切的问题,请不要犯我的愚蠢错误。我试图在Object.assign 中解构一个对象,而我应该只是传递该对象。 @Eldar 和 @Akxe 非常友好地让我重新审视代码并帮助我发现我在 cmets 中的错误。
问题:我正在尝试在 typescript 中为我的 redux 操作创建一个可重用的实体,这样我就可以在 reducer 中传递一个类型,但它抱怨我的类型不可迭代,我我不知道如何解决这个问题。我盲目地尝试添加typeof和Iterable无济于事,所以我正在寻找一些帮助和解释。
我的用户有一个实体:
export default interface UserEntity {
uid: string | null;
firstName: string | null;
}
并为我的操作创建了一个通用实体:
export default interface StoreAction<T> {
payload: T;
type: string;
}
在我的reducer中,我希望这样实现:
const initialState: UserEntity = {
uid: null,
firstName: null,
};
export default (state = initialState, action: StoreAction<UserEntity>) => {
switch (action.type) {
case 'Some string':
return Object.assign({}, state, ...action.payload); // Warning that action.payload is not iterable
default:
return state;
}
};
但是 VS Code 抱怨 Type 'UserEntity' must have a '[Symbol.iterator]()' method that returns an iterator. 虽然我明白它在抱怨什么,但我不知道如何解决它。
如果这里不是很明显,我想在这个UserEntity 的结构中向我的操作传递一个 json 的有效负载,然后能够使用扩展运算符将它与我的 redux 状态合并。我希望把它变成一个通用的,因为有些动作会有数组,有些可能只是一个布尔值,等等。redux 网站gives similar examples showing spread operators with interfaces 好像这应该可以工作,但我显然遗漏了一些东西。
编辑:添加我的 tsconfig.json:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"lib": [
"es6"
],
"allowJs": true,
"jsx": "react-native",
"noEmit": true,
"isolatedModules": true,
"strict": true,
"moduleResolution": "node",
"baseUrl": "./",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
},
"exclude": [
"node_modules",
"babel.config.js",
"metro.config.js",
"jest.config.js"
]
}
【问题讨论】:
-
在这些示例中,操作类型使用类型别名重新导出。喜欢:
export type SystemActionTypes = UpdateSessionAction。共享您的 ts.config 文件会很有用。 -
我添加了我的 tsconfig。我会尝试类型 - 你会建议我将我的界面导出为一种类型(或将其切换为一种类型),还是每个操作都需要是一种类型?我没有看到他们这样做,所以我会修补,但本着可重用的精神,我想我宁愿有一个动作工厂,并且能够向它传递一个动作类型字符串和一个可变类型的有效负载。建议?谢谢!
-
你不应该在那里解构它......,对象解构仅在对象定义内有效。错误是有效的。只需删除这三个点或使用
{ ...state, ...action.payload } -
@Akxe 是正确的,如果您将其更改为:
return Object.assign({}, state, {...action.payload}):,您将不会收到该错误。 -
不需要,很乐意提供帮助。
标签: reactjs typescript redux