Prisma Client CRUD 함수의 리턴 타입

이연중·2022년 1월 10일
0

노동일기(삽질)

목록 보기
3/3

문제점


Graphql 찍먹을 위해 작고 귀여운 개인 프로젝트를 진행하던 중 service layer에서 prisma orm을 통해 CRUD를 하는 코드의 타입 설정부분에서 다음과 같은 오류 덕분에 하루 정도 헤매었다....
(parameter) collectionId: string Type '(CollectionPlace & { collection: Collection; place: Place; })[]' is not assignable to type 'CollectionPlaceModel[]'. Type 'CollectionPlace & { collection: Collection; place: Place; }' is not assignable to type 'CollectionPlaceModel'. Types of property 'collection' are incompatible. Property 'user' is missing in type 'Collection' but required in type 'CollectionModel'.ts(2322) collection.model.ts(11, 3): 'user' is declared here.
그니까 쉽게 말해서 왜 너가 선언한 CollectionPlaceModel에는 collection 타입을 갖는 속성이 없냐는 것이었다.(아니 있는데 왜그러지...)

계속된 삽질 끝에 그 원인을 파악하게 되었다.


원인


prisma client를 이용한 CRUD 함수의 리턴값은 prisma client에 정의되어있는 즉, schema.prisma에 정의해놓은 타입(모델?)들이다.
해당 타입과 모양이 다르다면, 위와 같은 에러를 뱉는 것이다.

그렇다면 나의 코드의 prisma client를 이용해 CRUD를 하고 그에 대한 결과를 리턴하는 함수의 타입이 prisma client에 정의되어 있는 타입과 불일치한다는 것이라는 결론이 나온다.

어느부분인지 보면,

async getCollection(collectionId: string): Promise<CollectionPlaceModel[]> {
    return await this.prisma.collectionPlace.findMany({
      ...
    });
  }

위 코드의 리턴 타입 중 CollectionPlaceModel[]에 문제가 있는 것이다.

그럼 이제 CollectionPlaceModel이 어떻게 정의되어있는지를 본다.

import { Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { CollectionModel } from './collection.model';
import { PlaceModel } from '../../places/models/place.model';

import { Collection, CollectionPlace, Place } from '.prisma/client';

@ObjectType()
export class CollectionPlaceModel implements CollectionPlace {
  @Field(() => ID)
  id: string;

  @Field(() => CollectionModel)
  collection: CollectionModel;	//이 부분

  @Field(() => PlaceModel)
  place: Place;

  collectionId: string;
  placeId: string;
}

아하.... collection: CollectionModel 이 부분이 문제였던 것이다.
이유는 CollectionModel이라는 것은 내가 정의한 엔터티이고, 이는 prisma client에 정의된 스키마에 포함되지 않는 것이기때문이다.
즉, prisma client에서는 collection이라는 속성의 타입이 Collection(정의한 schema중 하나)라고 되어있는데, 위 코드에서는 CollectionModel(내가 정의한 엔터티)타입이라는 것이다.

++@Field(()=>CollectioModel) 부분은 왜 Collection이 아닌 CollectionModel로 써준 것일까?
해당 부분에는 값(value)가 들어가야 한다. 즉, 값으로 들어갈 수 있는 형식만이 저 부분에 들어갈 수 있는 것이다.(반대로 그렇지 못한 부분을 저곳에 할당하게 되면, 에러가 발생)


Collection은 type으로 취급된다. type은 컴파일 타임에만 남아있다(런타임에는 사라짐)
그래서 값이 될 수 없는 것이다.(interface도 마찬가지)
그래서 런타임에도 사라지지 않는 것들을 넣어야 하는 것이다.(class, const 등, 보통 class)
그래서 class 형식으로 된 엔터티인 CollectionModel을 넣어준 것이다.(모양은 Collection과 똑같음)


해결


해당 부분을 prisma client의 부분과 일치시켜줌으로써 해결하게 되었다.
collection: Collection
import {Collection} './prisma/client(prisma client에 정의되어있는 Collection 타입으로...)


깨달은 점


타입 설정에 관련해서 보다 더 디테일하게 신경쓰자!
어떤 타입을 리턴하는지 등등을 생각하면서!

profile
Always's Archives

0개의 댓글