{"record":{"id":"cacd6eb4d35e45c0","repo":"microsoft/TypeScript","slug":"private-accessor-was-defined-without-a-getter","errorCode":null,"errorMessage":"Private accessor was defined without a getter","messagePattern":"Private accessor was defined without a getter","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/compiler/factory/emitHelpers.ts","lineNumber":1287,"sourceCode":" *      __classPrivateFieldGet(<any>, <constructor>, \"f\", <{ value: any }>)\r\n *\r\n * Reading from a private static get accessor (when defined, TS 4.3+):\r\n *      __classPrivateFieldGet(<any>, <constructor>, \"a\", <function>)\r\n *\r\n * Reading from a private static get accessor (when not defined, TS 4.3+):\r\n *      __classPrivateFieldGet(<any>, <constructor>, \"a\", void 0)\r\n *      NOTE: This always results in a runtime error.\r\n *\r\n * Reading from a private static method (TS 4.3+):\r\n *      __classPrivateFieldGet(<any>, <constructor>, \"m\", <function>)\r\n */\r\nconst classPrivateFieldGetHelper: UnscopedEmitHelper = {\r\n    name: \"typescript:classPrivateFieldGet\",\r\n    importName: \"__classPrivateFieldGet\",\r\n    scoped: false,\r\n    text: `\r\n            var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {\r\n                if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n                if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n                return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n            };`,\r\n};\r\n\r\n/**\r\n * Parameters:\r\n *  @param receiver — The object on which the private member will be set.\r\n *  @param state — One of the following:\r\n *      - A WeakMap used to store a private instance field.\r\n *      - A WeakSet used as an instance brand for private instance methods and accessors.\r\n *      - A function value that should be the undecorated class constructor used to brand check private static fields, methods, and accessors.\r\n *  @param value — The value to set.\r\n *  @param kind — (optional pre TS 4.3, required for TS 4.3+) One of the following values:\r\n *       - undefined — Indicates a private instance field (pre TS 4.3).\r\n *       - \"f\" — Indicates a private field (instance or static).\r\n *       - \"m\" — Indicates a private method (instance or static).\r\n *       - \"a\" — Indicates a private accessor (instance or static).\r","sourceCodeStart":1269,"sourceCodeEnd":1305,"githubUrl":"https://github.com/microsoft/TypeScript/blob/b465fdbfe175304d9b977da137b2c178ae1091d3/src/compiler/factory/emitHelpers.ts#L1269-L1305","documentation":"Runtime TypeError thrown by the `__classPrivateFieldGet` downlevel helper that TypeScript emits when transpiling private accessors to targets below ES2022. The helper throws when `kind === \"a\"` (an accessor) but no getter function `f` was passed — i.e. the private accessor is write-only (declared with only a `set`). The compiler never throws this; only the emitted JavaScript does, when the write-only accessor is read.","triggerScenarios":"Reading a private accessor that has only a setter (`set #x(v){}` with no `get #x`), in code compiled with the `__classPrivateFieldGet` helper (target below ES2022, or downlevel private-member emit). Also reached by calling the helper directly with kind \"a\" and a falsy fourth argument.","commonSituations":"Downleveling a class that contains a setter-only private accessor and then reading that accessor from a method; refactoring a public accessor pair into private members and forgetting the getter; targeting older runtimes while using ES2022 private syntax.","solutions":["Add a `get` accessor to the private member so reads are valid.","Raise `target` to `ES2022`+ so native private fields are emitted and the helper is not generated.","Stop reading the write-only accessor at that call site — only assign to it.","If invoking the helper manually, pass a non-null getter function for kind \"a\"."],"exampleFix":"// before\nclass C {\n  set #acc(v: number) {}        // setter only, no getter\n  read() { return this.#acc; }  // runtime TypeError\n}\n// after\nclass C {\n  #v = 0;\n  get #acc() { return this.#v; }\n  set #acc(v: number) { this.#v = v; }\n  read() { return this.#acc; }\n}","handlingStrategy":"type-guard","validationCode":"// At authoring time the compiler flags reads of write-only accessors.\n// If you bypassed types with `any`, restore them so the read is caught statically:\nfunction readAcc(c: C) { return (c as any).#acc; } // avoid `any` casts on private members","typeGuard":"// Ensure every private accessor you read has a getter (compile-time):\ntype HasGetter<T> = T extends { readonly get: infer G } ? G : never;","tryCatchPattern":null,"preventionTips":["Keep `target` >= ES2022 when using private accessors to avoid the helper entirely.","Never read a private member through `any`; the type system is what prevents this.","When adding a private setter, add the matching getter unless write-only is intentional and never read."],"tags":["private-fields","runtime","downlevel","accessor","emit-helpers"],"backgroundTag":null,"analyzedSha":"b465fdbfe175304d9b977da137b2c178ae1091d3","analyzedAt":"2026-08-12T05:38:42.698Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}