• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

Redux type 설정 과정에서 발생한 오류 질문 (ts[2345])

23.05.31 16:22 작성 조회수 200

1

안녕하세요 redux 강좌 타입 강좌를 연습하는 과정에서 다음 코드에서 애러가 발생했습니다.

// 사용 패키지 버전
"redux": "^4.2.1",
"typescript": "^5.0.4"
"redux-thunk": "^2.4.2",

// redux.ts 코드에서 애러 발생

// initialState에서 애러 발생
const store = createStore(reducer, initialState, enhancer);

/*
Argument of type '{ user: { isLoggingIn: boolean; data: null; }; posts: never[]; }' is not assignable to parameter of type '{ user?: { isLoggingIn: boolean; data: { userId: number; nickname: string; } | null; } | undefined; posts?: undefined; }'.
Types of property 'posts' are incompatible.
Type 'never[]' is not assignable to type 'undefined'.ts(2345)
const initialState: {
    user: {
        isLoggingIn: boolean;
        data: null;
    };
    posts: never[];
}
*/
  • 이를 해석해 보았을 때, posts 속성에서 문제가 발생하고 undefined와 호완이 되지 않는다고 이해했습니다. 그래서 따로 타입을 만들어서 type assertion을 활용해서 타입을 주입해 보았습니다.

  • 하지만 여전히 애러가 발생하고 있습니다.

interface InitialState {
  user: {
    isLoggingIn: boolean;
    data: null | LoginSucessData;
  };
  posts: AddPostData[] | undefined;
}

const initialState = {
  user: {
    isLoggingIn: true,
    data: null,
  },
  posts: [],
};

const store = createStore(reducer, initialState as InitialState, enhancer);
/*
Argument of type 'InitialState' is not assignable to parameter of type '{ user?: { isLoggingIn: boolean; data: { userId: number; nickname: string; } | null; } | undefined; posts?: undefined; }'.
Types of property 'posts' are incompatible.
Type 'AddPostData[] | undefined' is not assignable to type 'undefined'.
Type 'AddPostData[]' is not assignable to type 'undefined'.ts(2345)
*/

결과적으로 강제로 any로 설정하면 애러가 해결이 되기는 하지만, 무언가 찝찝합니다.

const store = createStore(reducer, initialState as any, enhancer);

 

  • 그래서 해당 애러가 ts[2345] 애러라고 하여 검색을 해보았을 때, 데이터의 타입이 일치하지 않을 때 발생하는 애러와 연관이 있는 것 같았습니다. 어디서 타입의 불일치가 발생하는지 명확히 이해가 잘 안되어서 질문을 드립니다.

답변 2

·

답변을 작성해보세요.

0

이거 지금 보니까 user에 있는 initialState를 redux.ts에 있는 initialState에 제대로 합쳐두신 게 맞나요?

redux.ts의 initialState는 user와 post reducer의 initialState를 합쳐둔 것과 모양이 같아야 합니다.

redux.ts에서는 InitialState같은 타입이 필요 없습니다. 이런 타입은 각각의 리듀서에만 있으면 됩니다.

 

손준석님의 프로필

손준석

질문자

2023.06.01

감사합니다! initialstate와 reducer에서 반환 되는 값의 타입이 일치하지 않아서 발생하는 문제였습니다. 조금 더 고민해 보니 타입이 일치하지 않았다는 걸 알게 되었습니다.

0

const initialState: InitialState 로 타입을 넣어보세요

손준석님의 프로필

손준석

질문자

2023.05.31

interface InitialState {
  user: {
    isLoggingIn: boolean;
    loading: boolean;
    data: null | LoginSucessData;
  };
  posts: undefined | AddPostData[];
}

const initialState: InitialState = {
  user: {
    isLoggingIn: true,
    loading: true,
    data: null,
  },
  posts: [],
};

const store = createStore(reducer, initialState, enhancer);

 

알려주신 방법대로 해도 다음과 같이 ts[2345] 애러가 발생합니다!

Argument of type 'InitialState' is not assignable to parameter of type '{ user?: { isLoggingIn: boolean; data: { userId: number; nickname: string; } | null; loading: boolean; } | undefined; posts?: undefined; }'.Types of property 'posts' are incompatible.Type 'AddPostData[] | undefined' is not assignable to type 'undefined'.Type 'AddPostData[]' is not assignable to type 'undefined'.ts(2345)
const initialState: InitialState

여기서 posts가 undefind를 여전히 잡아내지 못하고 있는 것 같습니다.

 

export type RootState = ReturnType<typeof store.getState>;
/*
type RootState = EmptyObject & {
    user: InitialState;
    posts: never;
}
*/

더불어서 다음 과정을 진행 하였을때, RootState에서 post의 타입을 잡아내지 못하고 있습니다. 그럼에도 진행하는 과정에서는 문제가 없습니다.

userReducer쪽 보여주세요. 거기서 initialState 위치 타이핑 문제같습니다.

손준석님의 프로필

손준석

질문자

2023.05.31

import { Reducer } from "redux";
import {
  LoginAction,
  LogInRequestAction,
  LoginSucessData,
  LogOutAction,
} from "../action/user";

interface InitialState {
  isLoggingIn: boolean;
  data: LoginSucessData | null;
  loading: boolean;
}

const initialState = {
  isLoggingIn: false,
  data: null,
  loading: true,
};

type ReducerActions = LoginAction | LogOutAction | LogInRequestAction;

const userReducer: Reducer<InitialState, ReducerActions> = (
  prevState = initialState,
  action
) => {
  // 새로운 state 만들어주기
  switch (action.type) {
    case "LOG_IN_SUCCESS":
      return {
        ...prevState,
        data: action.data,
      };
    case "LOG_OUT":
      return {
        ...prevState,
        data: null,
      };
    default:
      return prevState;
  }
};

export default userReducer;

user reducer에서도 const initialState: InitialState 하세요.