Typescript: Tipo mapeado para hacer que cada propiedad sea de solo lectura excepto las propiedades elegidas
Me encontré con un desafío en el que no quería seguir reescribiendo múltiples interfaces.
Necesito que una interfaz sea completamente editable y también tener una 'copia' de esa interfaz donde todos los campos sean de solo lectura, excepto aquellos que seleccione para que sean editables.
TypeScript tiene tipos mapeados que pueden permitir esto.
Respuesta #1
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
Respuesta #2
Puedes usar el tipo utilitario Readonly de TypeScript:
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.
