Write TypeScript like a pro. Typescript Icon

Follow the ultimate TypeScript roadmap.

Public vs Private Properties and Methods in TypeScript

In this post you’ll learn how to create both public and private members in TypeScript classes, which we can use for both properties and methods.

JavaScript itself has no strict “private” capability, as per the design of the language, but with the addition of TypeScript in our workflow we get compile-time safety to stop private methods from being accessed.

What’s important to realize before we explore is even though properties and methods can be marked as public and private in TypeScript, they actually have no effect on the compiled output of our code.

By default all properties and methods, known as members, are public. Some developers enjoy using the public keyword alongside members but I feel like it’s not necessary due to TypeScript implicitly setting all members as public.

Let’s look at a basic class example:

class Product {
  name: string;
  price: number;
  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }
}

Based on what I’ve written above, we know that name and price are both public by default. Meaning, the above code is the same as below:

class Product {
  public name: string;
  public price: number;
  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }
}

If you want to use the public keyword, then feel free, but again I feel it’s not entirely necessary and creates more reading. We know things are public by default.

Now here’s where things get interesting, and before we look at private members let’s investigate the compiled TypeScript-to-JavaScript source code:

var Product = /** @class */ (function () {
  function Product(name, price) {
    this.name = name;
    this.price = price;
  }
  Product.prototype.getName = function () {
    return this.name;
  };
  return Product;
}());

Interesting! On the top level we have var Product which encapsulates a Product constructor function and is extended via the prototype with a getName function. This is done automatically for us to create private scope for our code.

But it’s not private, JavaScript has no private scope.

So what about the private keyword in TypeScript, maybe that helps us? Not quite, so don’t get carried away.

A property or method marked as private will simply throw an error if you try and access it from outside its scope boundary, for example a class.

class Product {
  private name: string;
  price: number;
  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }
}

const espresso = new Product('Espresso', 399);

// ❌ 'name' is private and only accessible within class 'Product'
console.log(espresso.name);

Similarly, if you mark a method as private it can only be used inside the class that defines it:

class Product {
  private name: string;
  price: number;
  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }
  private getName() {
    return this.name; // ✅ access allowed
  }
}

const espresso = new Product('Espresso', 399);

// ❌ 'getName' is private and only accessible within class 'Product'
espresso.getName();

All public properties are fully accessible outside of the class they’re created from, whereas all private properties and methods are not.

But… There is one thing you need to realize (and I’ve said it up top) - there is no private scope in JavaScript (yet…)!

So do not rely on the private keyword to solve your problems here. Want to see the output code from the above example using private?

Here:

var Product = /** @class */ (function () {
  function Product(name, price) {
    this.name = name;
    this.price = price;
  }
  Product.prototype.getName = function () {
    return this.name;
  };
  return Product;
}());

Yep, it’s exactly the same output whether or not you use public or private. TypeScript does not change JavaScript’s behavior when the code is compiled, and on the subject of private scope there is no silver bullet. The most we can do is encapsulate out logic within function scope and only expose methods we want to.

🏆 Check out my series of TypeScript Courses where you’ll learn TypeScript in-depth with real-world scenarios and examples to supercharge your JavaScript development.

That said, TypeScript takes care of some of the functionality for us, but when a class is compiled with private members, they will not be private. It is simply to stop you, and other developers, from accessing and using them in development.

Maybe one day we will see true “private” scope in JavaScript, until then be careful with whatever critical information you expose client-side, as if the code exists in the browser - it can be accessed and played with.

Learn TypeScript the right way.

The most complete guide to learning TypeScript ever built.
Trusted by 82,951 students.

Todd Motto

with Todd Motto

Google Developer Expert icon Google Developer Expert

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover