inflearn logo
강의

講義

知識共有

しっかりしたバックエンドNestJS、基礎から深化まで

passportと認証戦略&カスタムデコレータ

findCatByIdWithoutPassword 함수 리턴 타입 질문

324

xocoolree

投稿した質問数 1

1

  async findCatByIdWithoutPassword(id: string): Promise<Cat | null> {
    const cat = await this.catModel.findById(id).select('-password');
    return cat;
  }

위 함수에서 Pomise의 반환값이 Cat 또는 null인데 cat은 password가 없는 Cat이라서 Cat이라고 할 수 없는데 return을 cat으로 해도 에러가 안나는 이유를 알고 싶습니디.

node.js mongodb nestjs

回答 2

1

jehakim22oct8641

저도 그 문제를 고민해봐서 찾아본 결과를 공유하겠습니다.

우선 Cat의 경우, mongoose의 Document 클래스를 상속받았습니다.

그리고 findOne, findById, select 모두 Query<Document & Cat & { id }> 타입을 리턴합니다. (제네릭 타입은 무시했습니다)

&는 intersaction 기능을 수행하는 오퍼레이터로 Typescript 에서 서로 다른 필드는 합치고, 같은 필드는 더 작은 범위로 만들어줍니다. 자세한 내용은 공식문서를 참조하시거나 검색해보시면 더 잘 나오지만, 핵심은 이렇습니다.

Cat은 Document를 상속받았고,

&로 연결시켜도 Cat 에서 더 이상 변하지는 않습니다.

무엇보다도 아래 실험을 해보니 Typescript에서 허용하는 것이 있습니다:

class BaseClass {
  prop1: string;
}

class ClassA extends BaseClass {
  prop2: string | number;
}

type Combined = ClassA & BaseClass;

const combinedObject: BaseClass = {
  prop1: "1",
  prop2: 42,
} as ClassA; // Combined also ok

상속받아서 확장한 ClassA나 확장된 Combined 타입 모두 상속해준 Base클래스 타입으로 받는 것은 가능하고, 물론 동일한 타입끼리 선언하는 것도 가능합니다.

 

따라서, 우리가 작성했던 findOne이나 select를 통해 리턴된 값을 Promise<Cat>로 받는 것도 가능하고 Promise<Document>도 허용가능한 타입이 됩니다.

여기까지 제가 알아본 내용입니다.

도움이 되셨길 바랍니다.

0

communityai8509

안녕하세요, 인프런 AI 인턴이에요.

제시해주신 코드를 보면, findCatByIdWithoutPassword 함수는 catModel.findById(id) 메소드를 호출하여 해당 id에 해당하는 Cat 데이터를 가져오고 있습니다. 그리고 select(‘-password’)를 통해 가져온 Cat 데이터에서 password 필드를 제외한 데이터를 선택하고 있습니다.

이후에는 반환된 cat 데이터를 그대로 return하고 있습니다. 여기서 cat 데이터는 catModel.findById(id) 메소드의 반환 값이기 때문에 타입을 Cat으로 지정해줄 수 있습니다.

만약에 catModel.findById(id) 메소드의 반환 값이 null이거나 비어있는 경우, 해당 조건에 맞게 null을 반환하게 됩니다. 이렇게 된다면 Promise의 반환값은 Cat 또는 null이 될 수 있게 되는 것이죠.

그래서 위의 코드에서 cat으로 반환하더라도 에러가 발생하지 않는 이유는, cat이라는 변수에는 선택된 필드를 제외한 Cat 데이터 또는 null 값이 할당되기 때문입니다.

따라서 cat이라는 변수의 타입은 Cat 또는 null이 가능하게 되며, 이를 아래와 같이 Promise로 지정할 수 있게 되는 것이죠.

이와 관련해서 추가로 궁금한 점이 있다면 댓글로 알려주세요. 감사합니다.

참고로 위의 코드와 같은 내용을 구현할 때, 다른 개발자들이 코드를 이해하기 쉽도록 명시적으로 타입을 지정하는 것이 좋습니다. return 타입을 정확히 명시하는 것이 코드의 가독성을 높일 수 있습니다.

프로젝트 환경 세팅할 때 최신 노드 버젼을 사용하시는 분들은 참고하셔도 좋을 것 같아요~

2

77

1

DTO에 대한 질문

1

86

2

백엔드 MVC에서 View의 역할은 무엇인가요?

1

91

2

추가 업데이트 관련 건

0

89

2

nest js 버전문제

0

79

2

mongdb 스키마 공식 문서와 형태가 다른 이유 궁금합니다.

0

103

1

라인 끝에 에러 표시(eslint) 때문에 구글 찾아 보니.

0

72

1

전체 고양이 조회 라우터 중 error.message 오류

0

66

1

캡슐화 추가 설명 중 단일책임원칙 관련 질문

0

103

0

TypeORM과 mysql을 사용하시는 분들

4

140

1

42강 고양이끼리 소통 댓글 구현 중 Schema hasn't been registered for model 'comments' 에러 해결

0

80

1

채팅 이슈

0

132

1

모듈이 더 이상 지원하지 않는답니다

0

205

1

오류가 있습니다

0

105

1

import 에서 오류가 납니다

0

126

1

이런 오류가 나옵니다

0

99

1

에러가 발생합니다

0

108

1

프론트 에러 뜨는데 수정 안해주시나요

0

154

1

emit() broadcast.emit() 질문있습니다

0

100

1

서버연결이 안됩니다.

1

403

1

[PM2][ERROR] Command not found

0

517

1

S3에 업로드까지는 성공했는데 사진이 나오지 않습니다.

0

242

1

error_code : Property 'user' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.ts(2339)

0

600

1

jwt를 따로 연습하고 있는데 env를 못읽는 것 같습니다.

0

316

2