JSDoc tag

@protected

  • Checked by TypeScript
  • Since TypeScript 3.8

@protected on a class member allows it inside the class and inside every subclass, and nowhere else. Since TypeScript 3.8, a use from outside is an error (TS2445, "Property 'rows' is protected and only accessible within class 'Report' and its subclasses"). It is the JavaScript spelling of TypeScript's protected modifier.

Use it for the parts of a base class that subclasses build on, such as shared state or helper methods, but that callers should not touch.

At a glance

Use JSDoc in a .js file TypeScript in a .ts file
A protected member /** @protected */ rows = []; protected rows: string[] = [];

Examples

report.js report.ts Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: report.js(20,8): error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses. report.ts(18,8): error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. report.js(20,8): error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses. report.ts(18,8): error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. report.js(20,8): error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses. report.ts(18,8): error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses. checked 21 October 2026
export class Report {
  /** @protected */
  rows = /** @type {string[]} */ ([]);

  /** @param {string} row */
  add(row) {
    this.rows.push(row);
  }
}

export class CsvReport extends Report {
  toCsv() {
    return this.rows.join("\n");
  }
}

const report = new CsvReport();
report.add("TEE-01,2");
report.rows.length;error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses.
export class Report {
  protected rows: string[] = [];

  add(row: string) {
    this.rows.push(row);
  }
}

export class CsvReport extends Report {
  toCsv() {
    return this.rows.join("\n");
  }
}

const report = new CsvReport();
report.add("TEE-01,2");
report.rows.length;error TS2445: Property 'rows' is protected and only accessible within class 'Report' and its subclasses.
A @protected member, open to subclasses only.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
export.js export.ts TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
export class Exporter {
  /**
   * @protected
   * @param {string} value
   */
  quote(value) {
    return `"${value.replaceAll('"', '""')}"`;
  }
}

export class CsvExporter extends Exporter {
  /** @param {string[]} cells */
  row(cells) {
    return cells.map((cell) => this.quote(cell)).join(",");
  }
}

new CsvExporter().row(["TEE-01", "Cotton tee, large"]);
export class Exporter {
  protected quote(value: string) {
    return `"${value.replaceAll('"', '""')}"`;
  }
}

export class CsvExporter extends Exporter {
  row(cells: string[]) {
    return cells.map((cell) => this.quote(cell)).join(",");
  }
}

new CsvExporter().row(["TEE-01", "Cotton tee, large"]);
A @protected helper that subclasses call.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

What it allows

Inside CsvReport, this.rows is fine because CsvReport extends Report. From outside, report.rows fails even though report is a CsvReport. The second example shows a protected helper method that a subclass calls, which is the common case.

Gotchas

  • Like @private, the tag is a compile-time check; the property is ordinary at run time.
  • The accessibility tags do not work in constructor functions (see @private); use a class.
  • The protected keyword is TypeScript syntax and an error in a .js file (TS8009).

Questions

Can a subclass make a @protected member public?

Yes, as in TypeScript: redeclare it in the subclass without the tag (or with @public), and it is public on the subclass.

Sources

Last reviewed 20 October 2026.