React Redux Typescript -如何设置类型?



我很难设置这个函数的类型:

interface fetchedCountries {
mergedArray?: [];
}
export const fetchCountries = () => {
return (dispatch:(() => void)) => {
console.log(dispatch)
fetch(countryListJsonFile)
.then((response) => response.json())
.then((jsonData: fetchedCountries) => {
const array = Object.entries(jsonData)[0];
const countries = array[1].map((el: any) => {
return el._id;
}).sort();
dispatch(setCountries(countries));
})
.catch(function (err) {
console.error(err);
});
};
};

它说setCountries expected 0 arguments, but got 1.

我试着遵循不同的指南,比如这个,但我不能使它工作。我迷路了。我想在这里去掉所有的any类型,给出真实的类型。

商店已导出:

export type RootState = ReturnType<typeof store.getState>;
export type AppState = ReturnType<typeof rootReducer>;
export type AppDispatch = typeof store.dispatch;

这是切片:

import { createSlice } from '@reduxjs/toolkit';
const initialState = {
countryList: [],
};
const slice = createSlice({
name: 'countryList',
initialState,
reducers: {
setCountries(state, action) {
state.countryList = action.payload;
},
},
});
export const { setCountries } = slice.actions;
export default slice.reducer;

有人能帮忙吗?

您的代码中有几个问题都是相关的。您需要正确定义:

  1. fetchCountries函数中dispatch的类型。
  2. setCountries对应payload的类型。
  3. 您的状态类型。
  4. API响应的类型。

链中较高的类型不正确或缺失可能导致更低的问题。例如,当您发现自己在.map()回调中像这样设置类型时:

array[1].map((el: any) => {

表示数组本身(array[1])具有错误的类型。让我们来看看哪里出了问题。


1。调度类型

@T.D。石心是对的。expected 0 arguments, but got 1错误来自于调用dispatch(...),而不是调用setCountries(...)

你的定义dispatch:(() => void)dispatch不接受任何参数。这显然是错误的。

好消息是,在代码的其他地方已经有了正确的类型。它是您从存储文件中导出的AppDispatch
export const fetchCountries = () => {
return (dispatch: AppDispatch) => {

这个修复足以解决所有红色下划线错误。但是还有一些其他的错误和遗漏,你可能想要修正。


2。有效载荷类型

如果您没有显式地设置setCountries(state, action)的类型,那么您的有效负载类型将变为any。这很好,但并不理想。它说"一切皆有可能"。这使得很难发现真正的问题。

为操作分配正确的类型,为redux工具箱导入PayloadAction实用程序类型:

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

并将其与有效载荷类型一起使用,即一系列国家。看看你的坦克,这些似乎是string?:

reducers: {
setCountries(state, action: PayloadAction<string[]>) {
state.countryList = action.payload;      
},
},

3。国家类型

还记得我说过any可以隐藏真正的问题吗?如果你遵循了步骤2,那么你现在应该看到其中一个。

state.countryList = action.payload;的赋值错误:

类型'string[]'不能赋值给类型'never[]'.

你的state.countryList的类型是never[],因为它的初始值是[],这就是TypeScript所知道的。它不知道这应该是国家id的数组。你可以通过为你的initialState指定一个更精确的类型来解决这个问题。

const initialState = {
countryList: [] as string[],
};

或:

interface SliceState { // can name it whatever
countryList: string[];
}
const initialState: SliceState = {
countryList: [],
};

在这里有一个正确的类型将使使用从你的状态中选择的数据变得更加容易,因为现在RootState具有countryList属性的正确类型。


4。API响应类型

interface fetchedCountries {
mergedArray?: [];
}

此类型表示响应的JSON是一个对象它可能具有属性mergedArray这是一个空数组. 就是这样。

我不确定实际的数据是什么样子的,但也许是这样的?

interface Country {
_id: string;
}
interface FetchedCountries {
mergedArray: Country[];
}

所以现在你不需要使用(el: any)了,因为TypeScript已经知道el是一个Country对象。

.then((jsonData: FetchedCountries) => {
const countries = jsonData.mergedArray
.map(el => el._id)
.sort();
dispatch(setCountries(countries));
})

TypeScript Playground Link

实际上,问题在于返回函数的参数类型。

你返回了(dispatch: ((/* no parameters */) => void)) => {},但是你调用了dispatch(setCountries(countries)),它有一个参数setCountries(countries)。设置正确的参数数量将修复,如return (dispatch: ((something: unknown) => void)) => {}

最新更新