GraphQL3 min read

Mapped types

CRUD (Create/Read/Update/Delete) kabi funksiyalarni qurayotganda, ko'pincha bazaviy entity tipining variantlarini yaratish foydali bo'ladi. Nest bu vazifani yengillashtirish uchun

Warning

Bu bob faqat code first yondashuviga tegishli.

CRUD (Create/Read/Update/Delete) kabi funksiyalarni qurayotganda, ko'pincha bazaviy entity tipining variantlarini yaratish foydali bo'ladi. Nest bu vazifani yengillashtirish uchun type transformatsiyalarini bajaradigan bir nechta yordamchi funksiyalarni taqdim etadi.

Partial

Input validatsiya turlarini (Data Transfer Objects yoki DTOlar) qurayotganda, ko'pincha bir xil tipning create va update variantlarini yaratish kerak bo'ladi. Masalan, create variantida barcha maydonlar majburiy bo'lishi mumkin, update variantida esa barcha maydonlar ixtiyoriy bo'ladi.

Nest bu vazifani osonlashtirish va boilerplate ni kamaytirish uchun PartialType() yordamchi funksiyasini taqdim etadi.

PartialType() funksiyasi kiruvchi tipdagi barcha xossalari ixtiyoriy bo'lgan yangi tip (klass) qaytaradi. Masalan, bizda quyidagi create tipi bo'lsin:

TypeScript
1@InputType()
2class CreateUserInput {
3  @Field()
4  email: string;
5
6  @Field()
7  password: string;
8
9  @Field()
10  firstName: string;
11}

Default holatda, bu maydonlarning barchasi majburiy. Xuddi shu maydonlarga ega, lekin har biri ixtiyoriy bo'lgan tip yaratish uchun PartialType() dan foydalanib klass reference (CreateUserInput) ni argument sifatida bering:

TypeScript
1@InputType()
2export class UpdateUserInput extends PartialType(CreateUserInput) {}
Hint

PartialType() funksiyasi @nestjs/graphql paketidan import qilinadi.

PartialType() funksiyasi ixtiyoriy ikkinchi argument sifatida dekorator factoryga reference qabul qiladi. Bu argument natijaviy (child) klassga qo'llanadigan dekoratorni o'zgartirish uchun ishlatiladi. Agar ko'rsatilmasa, child klass amalda parent klassga (birinchi argumentda ko'rsatilgan klassga) qo'llangan dekorator bilan qoladi. Yuqoridagi misolda CreateUserInput @InputType() dekoratori bilan bezatilgan. UpdateUserInput ham @InputType() bilan bezatilgan bo'lishini xohlaganimiz uchun, InputType ni ikkinchi argument sifatida berish shart emas edi. Agar parent va child turlari boshqacha bo'lsa (masalan, parent @ObjectType bilan bezatilgan bo'lsa), ikkinchi argument sifatida InputType ni beramiz. Masalan:

TypeScript
1@InputType()
2export class UpdateUserInput extends PartialType(User, InputType) {}

Pick

PickType() funksiyasi kiruvchi tipdan xossalar to'plamini tanlab, yangi tip (klass) yaratadi. Masalan, quyidagi tipdan boshlaymiz:

TypeScript
1@InputType()
2class CreateUserInput {
3  @Field()
4  email: string;
5
6  @Field()
7  password: string;
8
9  @Field()
10  firstName: string;
11}

Ushbu klassdan xossalar to'plamini PickType() yordamchi funksiyasi bilan tanlashimiz mumkin:

TypeScript
1@InputType()
2export class UpdateEmailInput extends PickType(CreateUserInput, [
3  'email',
4] as const) {}
Hint

PickType() funksiyasi @nestjs/graphql paketidan import qilinadi.

Omit

OmitType() funksiyasi kiruvchi tipdan barcha xossalarni olib, so'ng muayyan kalitlar to'plamini olib tashlab yangi tip yaratadi. Masalan, quyidagi tipdan boshlaymiz:

TypeScript
1@InputType()
2class CreateUserInput {
3  @Field()
4  email: string;
5
6  @Field()
7  password: string;
8
9  @Field()
10  firstName: string;
11}

Quyida email dan tashqari barcha xossalarga ega hosila tip yaratamiz. Bu konstruktsiyada OmitType ning ikkinchi argumenti xossa nomlari massividir.

TypeScript
1@InputType()
2export class UpdateUserInput extends OmitType(CreateUserInput, [
3  'email',
4] as const) {}
Hint

OmitType() funksiyasi @nestjs/graphql paketidan import qilinadi.

Intersection

IntersectionType() funksiyasi ikkita tipni birlashtirib, yangi tip (klass) hosil qiladi. Masalan, quyidagi ikki tipdan boshlaymiz:

TypeScript
1@InputType()
2class CreateUserInput {
3  @Field()
4  email: string;
5
6  @Field()
7  password: string;
8}
9
10@ObjectType()
11export class AdditionalUserInfo {
12  @Field()
13  firstName: string;
14
15  @Field()
16  lastName: string;
17}

Biz barcha xossalarni ikkala tipdan birlashtiradigan yangi tip yaratamiz.

TypeScript
1@InputType()
2export class UpdateUserInput extends IntersectionType(
3  CreateUserInput,
4  AdditionalUserInfo,
5) {}
Hint

IntersectionType() funksiyasi @nestjs/graphql paketidan import qilinadi.

Composition

Type mapping yordamchi funksiyalarini bir-biri bilan kompozitsiya qilish mumkin. Masalan, quyidagisi CreateUserInput tipidagi barcha xossalarga ega bo'lgan, faqat email dan tashqari va bu xossalar ixtiyoriy bo'lgan tipni yaratadi:

TypeScript
1@InputType()
2export class UpdateUserInput extends PartialType(
3  OmitType(CreateUserInput, ['email'] as const),
4) {}