Mechanizm Partial<T> został wprowadzony w TypeScript, aby ułatwić pracę z obiektami, których właściwości mogą być tymczasowo nieokreślone. Historycznie deweloperzy musieli ręcznie tworzyć nowe typy, gdzie wszystkie właściwości stawały się opcjonalne, co prowadziło do duplikacji kodu i błędów.
Początkowo, aby zaktualizować lub stworzyć obiekty z opcjonalnymi polami, należało wyraźnie określić każdą opcjonalną właściwość, co było niewygodne i nie wspierało zmian w oryginalnym interfejsie. Tak powstał typ pomocniczy Partial<T>, który automatycznie zmienia wszystkie właściwości typu T na opcjonalne.
Przy projektowaniu API często wymagana jest aktualizacja tylko części obiektu, nie dotykając pozostałych pól. Jest to szczególnie istotne w przypadku zapytań PATCH, formularzy aktualizacji i funkcji zajmujących się tylko częścią danych. Bez Partial typizacja staje się skomplikowana i krucha.
Używa się typu pomocniczego Partial<T>, który jest zdefiniowany mniej więcej tak:
// Uproszczone: type Partial<T> = { [P in keyof T]?: T[P] };
W ten sposób wszystkie właściwości stają się opcjonalne. Przykład:
interface User { id: number; name: string; email: string; } function updateUser(id: number, user: Partial<User>) { // ... } // Można przekazać tylko zmieniane updateUser(1, { email: "test@example.com" });
Kluczowe cechy:
Czy można za pomocą Partial uczynić wszystkie pola oryginalnego interfejsu obowiązkowymi?
Nie, Partial czyni wszystkie właściwości opcjonalnymi. Dla odwrotnego zadania istnieje typ Required<T>.
Co się stanie, jeśli użyję Partial z już opcjonalnymi właściwościami?
Partial po prostu nie zmieni już opcjonalnych właściwości, wszystkie pola pozostaną opcjonalne, nawet jeśli były takimi przed zastosowaniem Partial.
Przykład:
interface X { x?: number; y: string; } const a: Partial<X> = {}; // obie właściwości teraz są opcjonalne
Czy można używać Partial dla zagnieżdżonych struktur, jeśli potrzeba uczynić opcjonalnymi tylko zagnieżdżone pola?
Partial nie rozprzestrzenia się rekurencyjnie na zagnieżdżone obiekty. Jeśli trzeba uczynić wszystkie zagnieżdżone właściwości opcjonalnymi — trzeba napisać własny typ generyczny lub użyć zewnętrznych narzędzi.
W systemie CRUD updateUser przyjmuje Partial<User> i pozwala na przekazywanie pustego obiektu, co prowadzi do błędów w czasie działania: wymagane pola są kasowane.
Zalety:
Wady:
Partial<User> jest stosowany tylko do opisywania formularza wejściowego aktualizacji. Na finalnym etapie wszystkie pola są walidowane i scalane z oryginalnym obiektem przed przekazaniem do bazy.
Zalety:
Wady: