inflearn logo
강의

Course

Instructor

[Renewal] TypeScript All-in-One: Part 2. Practical Analysis

Typing action, reducer

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

Resolved

375

kd021093477

5 asked

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[];
}
*/
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);

 

typescript redux

Answer 2

0

zerocho

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

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

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

 

0

kd021093477

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

0

zerocho

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

0

kd021093477

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의 타입을 잡아내지 못하고 있습니다. 그럼에도 진행하는 과정에서는 문제가 없습니다.

0

zerocho

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

0

kd021093477

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;

0

zerocho

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

타입 오버라이딩

0

77

2

React19에서 useRef 타입 정의의 변화

0

117

2

jQuery를 $로 한 번 더 감싼 형태

0

54

1

typescript interface를 jsdoc으로 주석달 때

0

226

2

declare module시 import 위치

0

195

2

declare global 로 선언된 타입을 확장하는게 아닌 좁히는것도 가능할가요?

0

145

2

typescript 강의를 보고 개발을 하다가 강의와 다른 내용인데 물어볼곳이 여기밖에 없어서 질문 드립니다.

0

234

1

강의에 필요한 사전준비와 예제 코드 첨부

1

308

1

local.ts 예제코드 첨부 합니다.

1

226

1

redux 예제코드 가져와서 강의 보면서 따라하는데

1

242

1

react 함수 컴포넌트 타이핑은 있는데 클래스 컴포넌트 타이핑 예제 코드가 없네요.

1

283

1

axios 1.6.0 버전으로 보고 있는데영

4

391

1

Module '"axios"' has no default export 에러 나시는분들

0

878

1

안녕하세요, 제로초님 타입스크립트 axios 분석 강의보고 궁금한점이 있어서 질문드립니다

1

386

1

안녕하세요. 제로초님 당신의 강의 매니아 입니다. typescript 모듈 관련 질문이 있어서요.

0

268

1

axios catch 에서 error 타입에 대해 as 없이 이렇게 사용하면 어떨까요?

0

405

1

global 선언 시 export {}

0

296

1

initialState가 제네릭 S인 이유가 잘 이해가 되지 않습니다.

0

308

1

declare module vs declare namespace

0

472

1

declare namespace vs namespace

0

493

2

"axios": "1.4.0" 버전 axios type 코드가 강의와 다릅니다!

0

555

1

index.d.ts 에서 global declare 선언을 했을 때와 하지 않았을 때의 차이

0

402

1

미들웨어가 커링패턴으로 이루어진 이유

0

434

1

axios 파트 첫번째 강의 질문입니다

0

530

1