Skip to content

Access Modifiers

TypeScript supports access modifiers for your class properties.

Public

In JavaScript, all class properties are public by default so there is no need to write the public keyword in your TypeScript files.

Private

In the code below, I have made the name property private.

class Cat {
    private name: string

    constructor(name: string) {
        this.name = name
    }
}

const CAT = new Cat('Cosmo')
console.log(CAT.name)

If you copy this script into the ./src/test.ts, the VSCode IDE and TSC will show an error.

Property 'name' is private and only accessible within class 'Cat'

But if you still compiled this using TSC anyway, it would still create a JavaScript compilation where the name property could still be used by the JavaScript outside of the Cat class.

Compile and run the code,

tsc -p ./src
node ./dist/test.js

Outputs

Cosmo

The JavaScript compilation ignored the private access modifier for the name method.

If you look at the JavaScript code at ./dist/test.js you'll see that the private keyword was actually ignored and not added. JavaScript does not support a private keyword.

Now since you are using TypeScript as a tool to help enforce some rules at design time, this is not really a major issue, since TSC and the VSCode IDE is telling you that you are using a private property outside of a class and you can fix your code while writing it.

But if you wanted to enforce private properties at the JavaScript compilation as well, rather than using the private keyword, you can use the # character in front of your property declarations and any usages of them. This will have the symptom of causing your JavaScript version of the code to syntax error which effectively makes the property private as a consequence.

So, copy this new code into `./src/test.ts',

class Cat {
    #name: string

    constructor(name: string) {
        this.#name = name
    }
}

const CAT = new Cat('Cosmo')
console.log(CAT.#name)

Compile and run,

tsc -p ./src
node ./dist/test.js

While that TSC and VSCode IDE are still telling you that there is a problem, but you compiled it anyway, the JavaScript version now does not run and breaks at the point where it tries to read the private property outside of the class.

console.log(CAT.);
                ^

SyntaxError: Unexpected token ')'

Protected

A protected property is accessible only internally within the class or any class that extends it but not externally.

In the code below, it is ok for the Cat class to reference the name property from Animal, but still not outside of the Animal or Cat classes.

class Animal {
    protected name: string
    protected age: number

    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
}

class Cat extends Animal {
    constructor(name: string, age: number) {
        super(name, age)
        console.log(this.name)
    }
}

const CAT = new Cat('Cosmo', 8)
console.log(CAT.name)

While TSC and the VSCode IDE indicate the error,

Property 'name' is protected and only accessible within class 'Animal' and its subclasses.

this code can still be compiled to JavaScript, and the JavaScript compilation will ignore the protected accessor and allow the name property to be used outside of the Animal and Cat classes regardless.

Outputs

Cosmo
Cosmo

There is no quick and easy way to enforce a protected relationship at the JavaScript compilation level, but it can still be useful to use at the TypeScript source level when developing and you want your code to honor a protected type of relationship.