Skip to content

Optional strict mode for readonly and shallowReadonly #8919

Open
@claudiaballano

Description

@claudiaballano

What problem does this feature solve?

The addition of strict mode to the readonly/shallowReadonly functions would bring significant benefits to developers by enhancing the reactivity system and improving debugging capabilities. Enabling strict mode on readonly variables would result in an error being thrown whenever an attempt to mutate them is made. This added safety measure ensures that all intents of mutations are explicitly tracked, making it easier to identify potential issues early in the development process.

In large projects with numerous components and complex data structures, it becomes crucial to maintain data integrity. Strict mode aids developers in confidently managing readonly variables, reducing the risk of unintentional mutations and maintaining the consistency of data across the application.

What does the proposed API look like?

const state = readonly({ count: 0 }, {strict: true}); // Enabling strict mode

export interface StrictMode {
  strict: boolean
}

export function readonly<T extends object>(
  target: T,
  strictMode?: StrictMode
): DeepReadonly<UnwrapNestedRefs<T>> {
  return createReactiveObject(
    target,
    true,
    readonlyHandlers(strictMode),
    readonlyCollectionHandlers,
    readonlyMap
  )
}

export const readonlyHandlers = (
  strictMode?: StrictMode
): ProxyHandler<object> => ({
  get: readonlyGet,
  set(target: object, key: string | symbol) {
    const setReadonlyErrorMessage = `Set operation on key "${String(
      key
    )}" failed: target is readonly.`
    if (strictMode?.strict) {
      throw new Error(setReadonlyErrorMessage, target)
    }
    if (__DEV__) {
      warn(setReadonlyErrorMessage, target)
    }
    return true
  },
  deleteProperty(target: object, key: string | symbol) {
    const deleteReadonlyErrorMessage = `Delete operation on key "${String(
      key
    )}" failed: target is readonly.`
    if (strictMode?.strict) {
      throw new Error(deleteReadonlyErrorMessage, target)
    }
    if (__DEV__) {
      warn(deleteReadonlyErrorMessage, target)
    }
    return true
  }
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions