CodexBloom - Programming Q&A Platform

TypeScript: implementing Mapped Types and Readonly Modifiers in a Generic Utility Type

👀 Views: 44 đŸ’Ŧ Answers: 1 📅 Created: 2025-06-12
typescript mapped-types generics TypeScript

I'm sure I'm missing something obvious here, but I'm working on a TypeScript utility type that transforms an object type by making all properties optional and readonly... I thought I could achieve this using mapped types, but I'm working with an unexpected behavior where the resulting type doesn't reflect the expected structure, especially when I use it with a generic type. Here's what I've come up with so far: ```typescript type ReadonlyOptional<T> = { [K in keyof T]?: Readonly<T[K]>; }; interface User { id: number; name: string; email: string; } type ReadonlyOptionalUser = ReadonlyOptional<User>; ``` When I try to use `ReadonlyOptionalUser`, I expect all properties to be both optional and readonly. However, when I try to create an object like this: ```typescript const user: ReadonlyOptionalUser = { name: "John", }; ``` I get the following TypeScript behavior: ``` Type '{ name: string; }' is missing the following properties from type 'ReadonlyOptional<User>': id, email ``` It seems that the optional properties aren't being treated as optional in the resulting type. I've also tried using `Partial` in combination with `Readonly`: ```typescript type ReadonlyOptional<T> = Partial<Readonly<T>>; ``` But that doesn't give the desired structure either. The goal is to create a utility that makes it easy to handle APIs where we might not receive all user fields. Any insights on what I might be doing wrong or how to fix this? I'm using TypeScript version 4.8.4, and I'm particularly curious if there is a better approach to achieve this functionality without running into these issues. For context: I'm using Typescript on Windows. Any help would be greatly appreciated!