Skip to content

fix: a modifier on a field named like an Object.prototype member throws at decoration #47

Closed

Description

@Upd4ting

attachModifier (src/modifiers/common.ts) decides whether a field already has modifiers with field in metaTable.fields. in also answers for inherited keys, so for a field named toString, valueOf, hasOwnProperty, isPrototypeOf, propertyIsEnumerable, toLocaleString or constructor it takes the "already modified" branch, reads Object.prototype[field] as the modifier list, and throws.

Reproduction

On main (0.1.11, pnpm run build first):

const lib = require("./dist/index.js");
class T extends lib.Table.with(lib.LocalizationModifier) {}
lib.Localized()(T.prototype, "toString");
// TypeError: Cannot read properties of undefined (reading 'modifier')

class U extends lib.Table.with(lib.HashModifier) {}
lib.Hashed()(U.prototype, "valueOf");
// TypeError: Cannot read properties of undefined (reading 'modifier')

With TypeScript decorators the same happens for @Localized() toString!: ... at class definition time.

Expected

The field gets its first modifier like any other name, or the decorator refuses the name with a clear error.

Notes

The same inherited-key lookup appears in ignoredEventNames (event in ignoredEventNames, src/modifiers/internal/kinds.ts), which silently skips modifier methods named like Object.prototype members as events. An own-key check (Object.hasOwn) or a Map fixes both, which is a behaviour change, so it was left out of the residual sweep refactor.

Activity

  1. Upd4ting commented on Nov 4, 2026

    @Upd4ting
    MemberAuthor

    Fixed by #53 (look up modified fields and event names by own key), landed on main (921bf9d, the landed campaign/integration PR #87). Checked on main with the issue's repro: @Localized on toString and @Hashed on valueOf no longer throw; src/tests/own_key_lookups.test.ts passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions