Parameter Properties in TypeScript

Parameter properties let you declare and initialize class fields directly in the constructor signature. Learn this TypeScript shorthand that eliminates repetitive boilerplate.

6 min read

TypeScript parameter properties are a shortcut that turns a constructor parameter into a class field with the same name and type. You write one word before the parameter name instead of three separate declarations.

Here is the manual way that you have seen in every class example so far:

typescripttypescript
class Point {
  x: number;
  y: number;
 
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}

And here is the same class rewritten using parameter properties instead, replacing the field declaration, constructor parameter, and manual assignment with a single modifier keyword:

typescripttypescript
class Point {
  constructor(
    public x: number,
    public y: number
  ) {}
}
 
const p = new Point(10, 20);
console.log(p.x, p.y);

This prints 10 20, the same result as the manual version above, since both classes end up with identical fields and identical emitted JavaScript.

texttext
10 20

The public keyword before x tells TypeScript to create a public field named x and assign the constructor argument to it. Both versions produce identical JavaScript. The parameter property version simply removes the repetition.

All Four Modifiers

You can use any access modifier on a parameter property, and they can be combined with readonly, exactly as you would on a manually declared field:

typescripttypescript
class User {
  constructor(
    public readonly id: number,
    public name: string,
    private email: string,
    protected role: string
  ) {}
}

All four fields are created from constructor parameters. The keywords determine visibility and mutability. Let us create an instance and see which fields are accessible:

typescripttypescript
const user = new User(1, "Ada", "ada@example.com", "admin");
console.log(user.id, user.name);

The id field is public and readonly, so anyone can read it but no one can change it. The name field is public and writable.

The email field is private, accessible only inside the User class. The role field is protected, accessible to User and its subclasses. Trying to read either from outside the class fails at compile time:

typescripttypescript
console.log(user.email);

TypeScript rejects this line at compile time, even though email is a real field on the instance, because private parameter properties are only visible inside the declaring class:

texttext
Property 'email' is private and only accessible within class 'User'.

All four fields are created and assigned from constructor arguments in a single line each, with no separate field declarations and no manual this.field = field assignments.

With Default Values

Parameter properties work with default values just like regular function parameters:

typescripttypescript
class Counter {
  constructor(
    public value: number = 0,
    public readonly step: number = 1
  ) {}
  increment() { this.value += this.step; }
}
 
const c1 = new Counter();
const c2 = new Counter(10, 5);
c1.increment();
c2.increment();
console.log(c1.value, c2.value);

This prints 1 15, since c1 uses both defaults (0 plus a step of 1) while c2 overrides both with the arguments 10 and 5.

texttext
1 15

The first counter starts at 0 with a step of 1. The second starts at 10 with a step of 5. Both constructors are clean one-liners thanks to parameter properties.

What Parameter Properties Do Not Do

Parameter properties only create a field from a constructor parameter. They do not add validation, transformation, or any other logic. If you need to validate or transform the value before storing it, use the manual approach instead:

typescripttypescript
class Temperature {
  constructor(public celsius: number) {
    if (celsius < -273.15) {
      throw new Error("Below absolute zero");
    }
  }
}

The parameter property creates the celsius field, but you can still add a constructor body with validation logic. The shorthand and the manual approach can coexist in the same constructor.

When to Use Parameter Properties

Use them when every constructor parameter maps directly to a field with the same name. This is common in:

  • Data transfer objects where the constructor just stores values.
  • Value objects like Point, Color, or Size.
  • Configuration classes that receive settings at construction time.

Skip them when the constructor parameter needs processing before storage, when the field name differs from the parameter name, or when the constructor body contains significant logic that makes the shorthand harder to read.

Common Mistakes

Forgetting to mark the field as readonly. If a value should never change after construction, write public readonly instead of just public. This prevents accidental reassignment throughout your codebase.

Using parameter properties for complex setup. If the constructor needs to call methods, validate deeply, or transform values before storing them, the manual approach with a constructor body is clearer. Parameter properties are best for straightforward data storage.

Confusing parameter properties with destructuring. Parameter properties use TypeScript-specific syntax with access modifiers. They are not related to JavaScript destructuring and cannot be used outside of class constructors.

For more on class field modifiers, see public private and protected in TypeScript and readonly class properties in TypeScript. For how constructors work in general, see constructors in TypeScript.

Rune AI

Rune AI

Key Insights

  • Prefix a constructor parameter with public, private, protected, or readonly to turn it into a class field automatically.
  • This replaces the three-step pattern: declare field, accept parameter, write this.field = field.
  • Parameter properties work with all access modifiers and can be combined with default values.
  • They are compile-time only. The emitted JavaScript is identical to the manual approach.
  • Use them for data-focused classes where every constructor parameter becomes an instance property.
RunePowered by Rune AI

Frequently Asked Questions

Do parameter properties change the emitted JavaScript?

No. A parameter property compiles to the same JavaScript as declaring a field and assigning it in the constructor separately. The shorthand is purely a TypeScript convenience that disappears during compilation.

Can I use parameter properties with default values?

Yes. You can combine a modifier like public readonly with a default value. For example, constructor(public x: number = 0) creates a public field x initialized to the argument or 0 if no argument is provided.

Do parameter properties work in abstract class constructors?

Yes. Abstract classes can use parameter properties in their constructors. The generated fields behave the same way as in concrete classes.

Conclusion

Parameter properties replace three lines of boilerplate with one word. Instead of declaring a field, writing a constructor parameter, and manually assigning this.field = field, you prefix the constructor parameter with public, private, protected, or readonly. TypeScript does the rest. The result is the same JavaScript either way, so there is no runtime cost to using this shorthand.