reactjs Redux Toolkit createSlice reducer类型错误

hgncfbus  于 2023-04-20  发布在  React
关注(0)|答案(1)|浏览(186)

我正在尝试使用Typescript创建一个新的React-Redux项目。到目前为止,一切都很棒(尽管我还没有做太多)。我对React和Redux有一定的经验,但是,它已经过时了,这也是我第一次深入研究Redux工具包。来自类型化背景,我喜欢在React中使用类型,直到我来到Slices。
我想从API加载大部分应用程序配置。所以我尝试定义初始状态(initState)和完全加载状态(ConfigurationState)。一切似乎都很好,但是,处理配置成功操作的reducer似乎不知道ConfigurationState类型。
我在WebStorm中工作,得到了错误TS2339: Property 'authClientId' does not exist on type 'SliceState'.   Property 'authClientId' does not exist on type 'initState'.,所有应该在ConfigurationState类型中定义的属性。
我一直在RTK定义初始状态的例子,我已经尝试了它的例子的各种组合。下面是我目前的reducer。
我有没有做错什么?

// The state we expect until configuration is loaded from the API
type initState = {
    configurationApi?: string;
    configurationId?: string;
    loading: LoadingState;
};

// The full state we expect once configuration is loaded.
type ConfigurationState = {
    configurationApi: string;
    configurationId: string;
    authClientId: string,
    authDomain: string,
    authPoolId: string,
    authRedirectSignIn: string,
    authRedirectSignOut: string,
    authRegion: string,
    loading: LoadingState;
};

// Slice state can be either our initial preloaded state, or fully loaded state.
// See https://redux-toolkit.js.org/usage/usage-with-typescript#defining-the-initial-state-type
type SliceState = initState | ConfigurationState;

const initialState = {
    configurationApi: process.env.REACT_APP_CONFIGURATION_API,
    configurationId: process.env.REACT_APP_CONFIGURATION_ID,
    loading: LoadingState.IDLE,
} as initState;

const configurationSlice = createSlice({
    name: 'configuration',
    initialState,
    reducers: {
        loadConfigurationStart(state) {
            if (state.loading !== LoadingState.PENDING) {
                state.loading = LoadingState.PENDING;
            }
        },
        loadConfigurationSuccess(state: SliceState, action: PayloadAction<ConfigurationState>) {
            state.loading = LoadingState.SUCCEEDED;
            state.authClientId = action.payload.authClientId;
            state.authDomain = action.payload.authDomain;
            state.authPoolId = action.payload.authPoolId;
            state.authRedirectSignIn = action.payload.authRedirectSignIn;
            state.authRedirectSignOut = action.payload.authRedirectSignOut;
            state.authRegion = action.payload.authRegion;
        }
    }
});

const { loadConfigurationStart, loadConfigurationSuccess } = configurationSlice.actions;

export default configurationSlice.reducer;
mrfwxfqh

mrfwxfqh1#

传递你的initialState as SliceState,或者更好的initialState satisfies SliceState as SliceState,(因为这样更安全)

const configurationSlice = createSlice({
    name: 'configuration',
    initialState: initialState satisfies SliceState as SliceState,
    reducers: {

在这一点之后,你就回到了正常的TypeScript行为。假设这段代码:

function someFunction(state: SliceState) {
  state.authClientId = "foo" // this will error
}

这是因为此时state可能是InitState(不允许authClientId)或ConfigurationState
此时,您只能将所有这些属性作为可选值添加到InitState中,这使得您的InitState类型首先变得毫无意义。(老实说,从一开始我就觉得这毫无意义)。

相关问题