How to fix A parameter property cannot be declared using a binding pattern in TypeScript
This TypeScript error occurs when trying to combine parameter properties (like public, private, readonly) with destructuring patterns in constructor parameters. Parameter properties provide shorthand syntax for declaring and initializing class members, but they cannot be used with object or array destructuring patterns.
Quick fix
Fixes A parameter property cannot be declared using a binding pattern
// Problematic code - causes TS1187 error
class Person {
constructor(public { firstName, lastName }: { firstName: string, lastName: string }) {
// Error: A parameter property cannot be declared using a binding pattern
}
}- Identify the problematic constructor parameter
- Separate parameter properties from destructuring
- Use traditional parameter properties without destructuring
- Create an interface for the parameter object
// Problematic code - causes TS1187 errorclass Person {constructor(public { firstName, lastName }: { firstName: string, lastName: string }) {// Error: A parameter property cannot be declared using a binding pattern}}A parameter property cannot be declared using a binding pattern
What this error means
TypeScript parameter properties are a convenient shorthand that allows you to declare and initialize class members directly from constructor parameters by adding modifiers like public, private, protected, or readonly. For example, `constructor(public name: string)` automatically creates a public `name` property. However, TypeScript does not support combining parameter properties with destructuring patterns (also called binding patterns). Destructuring allows you to extract values from objects or arrays directly in parameter lists, like `constructor({ firstName, lastName }: { firstName: string, lastName: string })`. The error "A parameter property cannot be declared using a binding pattern" occurs when you try to use both features together, such as `constructor(public { firstName, lastName }: { firstName: string, lastName: string })`. This syntax is not supported because it creates ambiguity in how the properties should be initialized and accessed.
Typical symptoms
- TypeScript compiler shows error TS1187: "A parameter property cannot be declared using a binding pattern"
- Code fails to compile when using public/private/readonly modifiers with destructured parameters
- IDE shows red squiggly lines under constructor parameters with both modifiers and destructuring
- Build process fails with TypeScript compilation error
Common causes
- Attempting to use parameter property modifiers (public, private, protected, readonly) with object destructuring in constructor parameters
- Trying to combine shorthand property declaration with pattern matching syntax
- Unsupported TypeScript syntax that mixes two different language features
- Following patterns from other languages that support similar syntax but TypeScript does not
How to fix "A parameter property cannot be declared using a binding pattern"
Look for constructor parameters that combine modifiers with destructuring patterns:
// Problematic code - causes TS1187 error
class Person {
constructor(public { firstName, lastName }: { firstName: string, lastName: string }) {
// Error: A parameter property cannot be declared using a binding pattern
}
}The issue is the public modifier before the destructured object { firstName, lastName }.
Instead of trying to combine both features, handle them separately. Extract the destructured parameters first, then assign them to class properties:
// Solution 1: Separate destructuring and property assignment
class Person {
firstName: string;
lastName: string;
constructor({ firstName, lastName }: { firstName: string, lastName: string }) {
this.firstName = firstName;
this.lastName = lastName;
}
}This approach maintains the destructuring convenience while explicitly declaring and assigning properties.
If you don't need destructuring, use standard parameter properties with individual parameters:
// Solution 2: Traditional parameter properties
class Person {
constructor(
public firstName: string,
public lastName: string
) {}
}
// Usage
const person = new Person('John', 'Doe');This is the most straightforward approach when you have simple parameters.
For complex objects, define an interface and use it in the constructor:
// Solution 3: Interface with explicit property declaration
interface PersonData {
firstName: string;
lastName: string;
age?: number;
}
class Person {
firstName: string;
lastName: string;
age?: number;
constructor(data: PersonData) {
this.firstName = data.firstName;
this.lastName = data.lastName;
this.age = data.age;
}
}
// Usage with object literal
const person = new Person({ firstName: 'John', lastName: 'Doe', age: 30 });This approach provides type safety and clear structure for complex parameter objects.
For very complex initialization scenarios, consider alternative patterns:
// Solution 4: Factory method
class Person {
private constructor(
public firstName: string,
public lastName: string,
public age?: number
) {}
static create(data: { firstName: string; lastName: string; age?: number }): Person {
return new Person(data.firstName, data.lastName, data.age);
}
}
// Usage
const person = Person.create({ firstName: 'John', lastName: 'Doe', age: 30 });This pattern separates object construction from the class definition and can handle more complex initialization logic.
Advanced notes
## Technical Background
Parameter properties and destructuring patterns are two distinct TypeScript features with different compilation requirements:
1. Parameter Properties: Compile to property declarations and assignments in the constructor
2. Destructuring Patterns: Compile to variable declarations and assignments from the parameter
Combining them creates ambiguity in the generated JavaScript. For example, what should constructor(public {x, y}) compile to? Should it create properties x and y on the instance, or just destructure into local variables?
## TypeScript Design Decision
The TypeScript team has considered this feature (see GitHub issue #5326) but hasn't implemented it due to semantic complexity. The main challenges include:
1. Property naming conflicts: How to handle cases where destructured variable names differ from desired property names
2. Access modifier application: Should modifiers apply to each destructured variable or the pattern as a whole?
3. Default values: How to combine parameter property modifiers with default values in destructuring
4. Nested patterns: How to handle deeply nested destructuring patterns
## Alternative Approaches in Other Languages
Some languages like C# support similar syntax with record types or primary constructors, but TypeScript's design constraints (compiling to JavaScript) make this more challenging to implement cleanly.
## Future Considerations
As TypeScript evolves, this feature might be added in future versions. Keep an eye on TypeScript release notes and the official GitHub repository for updates on this language feature request.
Frequently asked questions
- What does "A parameter property cannot be declared using a binding pattern" mean?
- TypeScript parameter properties are a convenient shorthand that allows you to declare and initialize class members directly from constructor parameters by adding modifiers like public, private, protected, or readonly. For example, constructor(public name: string) automatically creates a public name property. However, TypeScript does not support combining parameter properties with destructuring patterns (also called binding patterns).
- How do I fix "A parameter property cannot be declared using a binding pattern"?
- This TypeScript error occurs when trying to combine parameter properties (like public, private, readonly) with destructuring patterns in constructor parameters. Parameter properties provide shorthand syntax for declaring and initializing class members, but they cannot be used with object or array destructuring patterns.
- What causes "A parameter property cannot be declared using a binding pattern"?
- Attempting to use parameter property modifiers (public, private, protected, readonly) with object destructuring in constructor parameters Trying to combine shorthand property declaration with pattern matching syntax Unsupported TypeScript syntax that mixes two different language features
- Is the "A parameter property cannot be declared using a binding pattern" error serious?
- It is a low-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐TypeScript Official Documentation
- ๐Github.com - 5326(GitHub)
- ๐Typescriptlang.org - variable-declarations.html(Official Docs)
- ๐Typescriptlang.org - classes.html(Official Docs)
- ๐