Skip to content

Instantly share code, notes, and snippets.

@andostronaut
Last active July 27, 2023 16:10
Show Gist options
  • Save andostronaut/8300bcecca0d56ccee35b48aba2c0e28 to your computer and use it in GitHub Desktop.
Save andostronaut/8300bcecca0d56ccee35b48aba2c0e28 to your computer and use it in GitHub Desktop.
Using DeepReadonly, we cannot mutate anything in the entire tree, preventing a whole range of bugs that could occur.
export function EditEvent() {
const [event, setEvent] = useState<DeepReadonly<Event>>()
// ...
// ❌
event.attendees.push('foo') // Error
// ✅
setEvent({
...event,
title: e.target.value,
attendees: [...event.attendees, 'foo']
})
}
export type DeepReadonly<T> =
T extends Primitive ? T :
T extends Array<infer U> ? DeepReadonlyArray<U> :
DeepReadonlyObject<T>
type Primitive =
string | number | boolean | undefined | null
interface DeepReadonlyArray<T>
extends ReadonlyArray<DeepReadonly<T>> {}
type DeepReadonlyObject<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment