Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Mapped type to make every property readonly except chosen properties

I ran into a challenge where I didn't want to keep rewriting multiple interfaces.

I need one interface to be fully writable, and also have a "copy" of that interface where all fields are readonly except those that I select to be writeable.

Typescript has mapped types which may allow this.

like image 860
George43g Avatar asked Nov 30 '25 16:11

George43g


2 Answers

export type DeepReadOnly<T> = { readonly [key in keyof T]: DeepReadOnly<T[key]> };
export type DeepMutable<T> = { -readonly [key in keyof T]: DeepMutable<T[key]> };
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export type DeepKeepMutable<T, K extends keyof T> = DeepReadOnly<Omit<T, K>> & DeepMutable<Pick<T, K>>;

// use as follows
let o: DeepKeepMutable<Metadata, 'time' | 'payload'>;
// this will keep time and payload writeable while the rest are readonly

// it is also possible to extend and modify these types with index signatures, optional properties and level of depth

like image 109
George43g Avatar answered Dec 02 '25 05:12

George43g


You can use TypeScript's Readonly utility type:

type SomeType = {
  a: string;
};

const s: SomeType = {
  a: "can modify",
};

s.a = "new value";
// ^ Can modify

type ReadOnlyType = Readonly<SomeType>;

const r: ReadOnlyType = {
  a: "cannot modify",
};

r.a = "new value";
// ^ ERROR! - Cannot assign to 'a' because it is a read-only property.

like image 24
Diego M.F. Avatar answered Dec 02 '25 05:12

Diego M.F.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!