Poznajemy w TypeScript utility types Partial oraz Required i uczymy się samemu ich pisać. Lekcja krótka i przyjemna, zaczynajmny!

Ok, required z dokumentacji:

interface Props {
  a?: number;
  b?: string;
}
 
const obj: Props = { a: 5 };
 
const obj2: Required<Props> = { a: 5 };
//Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>'.

Jak widać, required sprawia, że wszystkie pola, które były nieobowiązkowe, teraz obowiązkowe są. Dodatkowo, pola obowiązkowe nadal obowiązują.

Teraz partial:

interface Todo {
  title: string;
  description: string;
}
 
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
  return { ...todo, ...fieldsToUpdate };
}

Już teraz możemy się domyślić, że partial wymaga, aby tylko niektóre pola były wypełnione. Dokładniej wygląda to tak:

const todo1 = {
  title: "organize desk",
  description: "clear clutter",
};
 
const todo2 = updateTodo(todo1, {
  description: "throw out trash",
});

Ok, zobaczmy jak wygląda Required:

type Req<T> = {
    [P in keyof T]-?: T[P];
}

Minusik oznacza, że zdejmujemy flagę ?, jeżeli występuje. A partial?

type Partial2<T> = {
    [P in keyof T]?: T[P];
};

Tutaj do każdego P dodajemy flagę ?. Czyli, żebyśmy się dobrze zrozumieli, mogą być tylko takie properties, jakie ma T. Ale wszystkie są nieobowiązkowe.

I jeżeli zobaczymy jak edytor wyświetla typ Partial2 to zobaczymy coś innego:

type Partial2<T> = {
    [P in keyof T]?: T[P];
};
// type Partial2<T> = { [P in keyof T]?: T[P] | undefined; }

No to jest oznaczenie, że undefined może być zwrócone. Chyba logiczne. Tak też docsy TSa wyświetlają typ Partial.

Partial jest dobry, aby coś krok po kroku tworzyć, albo modyfikować pewne rzeczy, tak jak w tamtym przykładzie. Required zaś dodaje wszystkie pola jako konieczne, też ma swoje zastosowania.

Więcej TSa niedługo!