TypeScript - Why does a name get displayed when there is a private class inside a public constructor

105 views Asked by At

I have this Try it Yourself TypeScript Parameter Properties example from W3Schools in the screenshot below.

TypeScript Classes Parameter Properties example

I am a bit confused as to why the name Jane gets displayed to the screen when there is this code.

My understanding is that the code below assigns a a variable to a class Person

const person = new Person ("Jane")

console.log code calls a getName() function with this code

console.log(person.getName())

Inside class Person, a public visibility modifier has a function that returns a name with

public getName(): string  { 
   return this.name; 
}

But how can it get the name when this code has a private member variable inside a public constructor

public constructor(private name: string) {}

I though that a private member only allows access to a class member (in this case name) from within the class

How does it work when you have a private member within a public constructor like this ?

If someone can give me a good understanding on why it can still work like this, then that will be appreciated help, thanks ?

2

There are 2 answers

0
Parth Raval On

Note:- Constructor of class 'Person' is public and it can be accessible within & outside of the class declaration.

"use strict";

class Person {
    public constructor(private name: string) { }
    public getName(): string {
        return this.name;
    }
}

const person  = new Person("Jane");

console.log(person);

Output you will get:

Person: { "name": "Jane" }

Now, If you don't want to access class 'Person' out side then you need to change public access modifiers to private and then that member can only accessible within the class declaration.

"use strict";

class Person {
    private constructor(private name: string) { }
    private getName(): string {
        return this.name;
    }
}

const person  = new Person("Jane");

console.log(person);

Error you will get:

  1. Constructor of class 'Person' is private and only accessible within the class declaration.
  2. 'getName' is declared but its value is never read.

For more details please check this link typescriptlang access modifiers

0
Rob Wilkinson On

I have had a look at this question in terms of what the code means from 2 perspectives.

  1. Code as it is shown in screenshot
  2. How the private part works

Here is code from screenshot explained :

class Person {
// A class is created here and this is a template for the object within it.
  
  public constructor(private name: string) {}
  /* A constructor is a method that runs every time a new instance of a 
     class is created. It is a method called when creating an object and 
     it can be used to initialize values in a class. 
     By default constructors use a public visibility modifier, so 
     this is same as constructor(private name: string). */

  /* (private name: string) is a parameter of string type that can be 
     used as a class member for getName() function only within this 
     class. */

  public getName(): string {
  // A function that gets name parameter as a string type.

    return this.name;
    /* Now we want to access a name member of this class, which is the 
       parameter here and display property value as a string on screen. 
    */
  }
}
      
const person = new Person("Jane");
/* Here an object of a class is created using new keyword that 
   creates a new instance of a class, so object person is of type 
   Person class.
   Happens first in process, where it assigns an object as a variable to 
   Person class and includes a name parameter with a property value of 
   Jane. */

console.log(person.getName());
/* Console calls a getName() function in Class Person by using an 
   internal method with public getName(): string . That picks up a name 
   parameter with string type from public constructor and displays 
   property value on screen. */

The result of this code, is that Jane gets displayed on screen

This works because a parameter method in public constructor is used for a name property that uses a public getName() function to allow access to a class member from anywhere.

It also works because we have console code use a function below to access a property value within class :

console.log(person.getName());

You can also change code below Class Person to access whole class

const person = new Person("Jane");

console.log(person);

and it works, as well with this output.

Person: { "name": "Jane" }

Now if we were to change the way we access with person.name = "Jane" as shown with code below

class Person {
  //Can use private name: string here and it will work in same way

    public constructor(private name: string) {
    // Can use public constructor(name) here and it will work in same way

  }

  public getName(): string {
    return this.name;
  }
}
      
const person = new Person("Jane");

person.name = "Jane"

console.log(person);

Then following error appears with

prog.ts(17,8): error TS2341: Property 'name' is private and only accessible within class 'Person'.

So this shows that a private class member cannot be accessed outside of a class as a property of an object.

The process also works the same with readonly as well in terms of access

and readonly prevents a class member from being changed with this error.

prog.ts(16,8): error TS2540: Cannot assign to 'name' because it is a read-only property.

Lastly if all class members are private, you cannot access a property from any of these methods, I have mentioned and will get a private error.