TS 비구조화할당에서 나머지속성의 타입 정의

class User {
  id: number;
  email: string;
  username: string;
  password?: string;
  registeredAt: Date;
  updatedAt: Date;
  updatedPasswordAt: Date;
}

interface SafeUserAssignment {
  password: string;
  safeUser: User;
}

const getUser = async (id: number): Promise<User> => {
  const user: User = await pool.connection()
    .get(User)
    .where({ id });
  
  const { password, safeUser }: SafeUserAssignment = user;
/*      ----------------------
TS2741: Property 'safeUser' is missing in type 'User' but required in type 'SafeUserAssignment'. */
  
  return safeUser;
}

제가 DB에서 사용자 정보를 가져온다음에 패스워드 필드만 없애고 전달해주려고 합니다. (클라이언트에게 API 응답으로 넘겨줄 용도)

그래서 위 코드처럼, password를 옵셔널로 바꾼다음에 (사실 이것도 찜찜하긴 합니다.)
비구조화할당 하면서 password를 뺀 나머지 속성만 나머지속성에 담아서 새로운 변수로 선언하려고 합니다.

그랬는데 해당 부분에 에러표시가 되면서

TS2741: Property ‘safeUser’ is missing in type ‘User’ but required in type ‘SafeUserAssignment’.

라고 에러가 뜨네요

우선 비구조화할당에서 타입정의는


이거보고 했는데
제 코드는 비구조화할당과 더불어 나머지속성 문법도 같이 써서 스택오버플로우와 다른 결과가 나오는것 같습니다…

비구조화할당 하는 코드에서 타입 정의를 따로 안하고, any로 냅둔다음에
그 다음줄에서 쓸데없이 변수를 하나 더 선언해서 거기에 타입 정의하면서 safeUser를 그대로 대입해주면 잘 되긴 합니다.

하지만… 왠만하면 그렇게 이상한 방법으로 풀지 않는 방법을 배우고 넘어가고 싶은데요

어떻게 하면 좋을까요?

그리고, 추가적인 질문이 있는데요.

지금 저처럼… 클래스/인터페이스로 이미 선언되어있는 객체타입에서
특정 속성만 제거해서 그 속성만 제외된 새로운 타입으로 선언해서 쓰고싶을때가 비즈니스 로직에서 의외로 은근 있을것 같은데요…
저는 TS배우면서 개인프로젝트로 하는거니깐 DB 필드정보와 연동되어있는 클래스를 옵셔널로 바꿔도 됐지만, 실제론 이런식으로 해결을 하면 안될것같은데요.

보통 이럴때 어떻게 해결하시나요?

interface에서 특정 필드만 제거하는 경우 Omit을 사용하면 됩니다.

class User {
  id: number;
  email: string;
  username: string;
  password?: string;
  registeredAt: Date;
  updatedAt: Date;
  updatedPasswordAt: Date;
}

type SafeUser = Omit<User, "password">;

그리고 비구조화 할당시에 굳이 타입을 붙이실 필요가 있을까 싶습니다.
아마 자동으로 safeUser에는 Omit<User, “password”>로 지정이 될겁니다.

1 Like

오… 감사합니다ㅜㅜ