DeepPartial được tạo bằng recursive conditional type: nếu T là object thì áp dụng optional modifier cho mỗi key và đệ quy vào giá trị con, ngược lại trả về T nguyên bản (type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T).
- DeepReadonly cần xử lý riêng trường hợp array bằng cách kiểm tra T extends (infer U)[] trước để chuyển thành
ReadonlyArray<DeepReadonly<U>>, sau đó mới xử lý object bằng cách thêm readonly modifier cho tất cả keys và đệ quy tiếp. - Việc tách riêng logic cho array là bắt buộc vì array có semantics khác với object thông thường, nếu không sẽ mất đi các array methods và tính đúng đắn của kiểu dữ liệu.
DeepPartial is created using a recursive conditional type: if T is an object, apply the optional modifier to each key and recurse into child values, otherwise return T as-is (type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T).
- DeepReadonly needs to handle arrays separately by checking
T extends (infer U)[]first to convert them toReadonlyArray<DeepReadonly<U>>, then handle objects by adding readonly to all keys and recursing. - Separating array logic is mandatory because arrays have different semantics from plain objects, otherwise array methods and type correctness would be lost.