This TypeScript error occurs when you have duplicate parameter names in function signatures, method overloads, or interface definitions. The fix involves renaming duplicate parameters, using different parameter names in overload signatures, or restructuring your code to avoid naming conflicts.
The "Parameter must have a unique name" error in TypeScript occurs when you have duplicate parameter names within the same function signature, method overload, or interface definition. TypeScript requires all parameters to have unique names within their scope to prevent ambiguity and ensure type safety. This error typically appears in several scenarios: 1. **Duplicate parameter names in a single function**: When you accidentally use the same parameter name twice in a function declaration. 2. **Method overload signatures with duplicate parameter names**: When overloaded methods have parameters with the same name but different types, causing confusion. 3. **Interface/type definitions with duplicate properties**: When defining interfaces or types with properties that have the same name. 4. **Destructuring parameters with duplicate names**: When using object destructuring in parameters with conflicting property names. TypeScript raises this error because duplicate parameter names can lead to: - Ambiguity in type inference - Confusion about which parameter is being referenced - Potential runtime bugs if the wrong parameter is used - Issues with documentation and code readability The error is part of TypeScript's strict type checking system designed to catch common mistakes early in the development process.
The most common cause is having the same parameter name twice in a function signature:
// WRONG - duplicate parameter 'x'
function calculate(x: number, x: number): number {
return x + x; // Which 'x' is being referenced?
}
// CORRECT - unique parameter names
function calculate(x: number, y: number): number {
return x + y;
}
// WRONG - duplicate in arrow function
const process = (data: string, data: string) => {
console.log(data); // Ambiguous
};
// CORRECT - unique names
const process = (input1: string, input2: string) => {
console.log(input1, input2);
};
// WRONG - duplicate in method
class Calculator {
add(a: number, a: number): number { // Error
return a + a;
}
}
// CORRECT
class Calculator {
add(a: number, b: number): number {
return a + b;
}
}How to fix:
1. Examine the function signature highlighted by TypeScript
2. Identify which parameter names are duplicated
3. Rename one of the parameters to a unique name
4. Update all references to that parameter within the function body
5. Ensure the new name accurately describes the parameter's purpose
Method overloads in TypeScript must have unique parameter names across all signatures:
// WRONG - duplicate 'value' parameter in overloads
interface Parser {
parse(value: string): Document;
parse(value: number): Document; // Error: duplicate 'value'
}
// CORRECT - different parameter names or restructure
interface Parser {
parse(strValue: string): Document;
parse(numValue: number): Document; // OK - unique name
// Alternative: single method with union type
parse(input: string | number): Document;
}
// WRONG - overloads with same parameter names
function format(data: string): string;
function format(data: number): string; // Error
function format(data: string | number): string {
return String(data);
}
// CORRECT - unique names or union type approach
function format(text: string): string;
function format(value: number): string; // OK - 'value' vs 'text'
function format(input: string | number): string {
return String(input);
}
// Better: Single signature with union type
function format(input: string | number): string {
return String(input);
}Best practices for overloads:
1. Use descriptive, unique parameter names for each overload
2. Consider if overloads are necessary vs. using union types
3. Document each overload's purpose clearly
4. Keep overload signatures minimal (2-3 at most)
Interfaces and type aliases cannot have duplicate property names:
// WRONG - duplicate 'id' property
interface User {
id: string;
name: string;
id: number; // Error: duplicate 'id'
}
// CORRECT - unique property names
interface User {
id: string;
name: string;
userId: number; // Different name
}
// WRONG - type alias with duplicate
type Config = {
path: string;
path: string; // Error
};
// CORRECT
type Config = {
sourcePath: string;
destPath: string;
};
// WRONG - intersection types creating duplicates
type A = { x: string };
type B = { x: number };
type C = A & B; // Creates 'x: string & number', not duplicate
// For extending interfaces, use 'extends' properly
interface Base {
id: string;
}
interface Extended extends Base {
id: number; // Error: conflicts with Base.id
// CORRECT: use a different name or omit
numericId: number;
}How to fix interface/type issues:
1. Check for typos or accidental duplicates
2. Use more specific property names
3. Consider if you need separate interfaces
4. Use mapped types or utility types if appropriate
Destructuring in function parameters can create naming conflicts:
// WRONG - destructuring creates duplicate 'id'
function processUser(
{ id, name }: { id: string, name: string },
id: number // Error: duplicate 'id'
) {
console.log(id); // Which id? string or number?
}
// CORRECT - rename destructured parameter
function processUser(
user: { id: string, name: string },
userId: number // Unique name
) {
console.log(user.id, userId);
}
// Alternative: rename during destructuring
function processUser(
{ id: userId, name }: { id: string, name: string },
id: number
) {
console.log(userId, id); // Clear distinction
}
// WRONG - nested destructuring conflicts
function updateConfig(
{ db: { host } }: { db: { host: string } },
host: string // Error: duplicate 'host'
) {
// ...
}
// CORRECT
function updateConfig(
config: { db: { host: string } },
serverHost: string
) {
console.log(config.db.host, serverHost);
}Destructuring best practices:
1. Use descriptive names for destructured variables
2. Rename during destructuring if names conflict: { id: userId }
3. Consider using the full object if destructuring creates confusion
4. Keep destructuring simple and readable
Generic type parameters can conflict with regular parameters:
// WRONG - generic 'T' conflicts with parameter 'T'
function identity<T>(T: T): T { // Error: duplicate 'T'
return T;
}
// CORRECT - different names
function identity<T>(value: T): T {
return value;
}
// WRONG - multiple generics with same name
function merge<T, T>(a: T, b: T): T[] { // Error
return [a, b];
}
// CORRECT
function merge<T, U>(a: T, b: U): (T | U)[] {
return [a, b];
}
// WRONG - generic in class conflicts with method parameter
class Container<T> {
set(value: T, T: string): void { // Error
// ...
}
}
// CORRECT
class Container<T> {
set(value: T, tag: string): void {
// ...
}
}Generic naming conventions:
1. Use single uppercase letters: T, U, V for simple generics
2. Use descriptive names for complex generics: TKey, TValue
3. Avoid using generic names as parameter names
4. Follow project naming conventions for consistency
Configure your development environment to catch these errors early:
// tsconfig.json - recommended settings
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noUnusedParameters": true,
// These help catch duplicate parameter issues
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
// For better error messages
"pretty": true,
"diagnostics": true
}
}Development tools and practices:
1. IDE/Editor configuration:
- Enable TypeScript strict mode in your editor
- Use ESLint with TypeScript rules: @typescript-eslint/no-duplicate-parameters
- Configure automatic imports to avoid naming conflicts
2. Code review practices:
- Check for parameter naming consistency
- Review overloaded method signatures
- Verify interface and type definitions
3. Automated testing:
- Run TypeScript compiler as part of CI/CD
- Use tsc --noEmit to check types without building
- Add linting to pre-commit hooks
4. Refactoring tools:
- Use IDE rename refactoring to update all references
- Consider using codemods for large-scale renames
- Use TypeScript's "Rename Symbol" feature
Prevention tips:
- Use descriptive, specific parameter names
- Follow a naming convention (e.g., prefix with type: strName, numCount)
- Keep functions small with few parameters
- Use interfaces/types for complex parameter objects
- Regularly run TypeScript checks in development
### Understanding TypeScript's Parameter Scoping Rules
TypeScript follows JavaScript's scoping rules with additional type safety:
1. Function scope: Parameters are scoped to their function body
2. Block scope: let/const declarations create block scope (ES6+)
3. Temporal dead zone: Parameters can't reference later parameters
// Parameters are available throughout the function
function example(a: number, b: number = a * 2) { // OK: 'a' is defined
return a + b;
}
// But not in reverse order
function invalid(b: number = a * 2, a: number) { // Error: 'a' not defined
return a + b;
}### Method Overload Implementation Details
When TypeScript checks overloads, it verifies:
1. All overload signatures are compatible with the implementation
2. Parameter names are unique across overloads
3. Return types are assignable
// Implementation must handle all overload cases
function process(input: string): string;
function process(input: number): number;
function process(input: string | number): string | number {
if (typeof input === 'string') {
return input.toUpperCase();
} else {
return input * 2;
}
}### Interface Merging and Declaration Merging
TypeScript allows interface merging, which can create implicit duplicates:
// In file1.ts
interface Config {
port: number;
}
// In file2.ts
interface Config {
port: string; // Error when merged: duplicate 'port'
host: string;
}
// Result: Config has conflicting 'port' types### Using Type Guards and Assertions
When you need to distinguish between similar parameters:
function process(input1: unknown, input2: unknown): void {
// Type guards help distinguish
if (typeof input1 === 'string' && typeof input2 === 'number') {
console.log(input1, input2);
}
}
// Type assertions when you know the types
function safeParse(json1: string, json2: string): [any, any] {
return [JSON.parse(json1), JSON.parse(json2)];
}### Performance Considerations
Duplicate parameter checking happens during:
1. Parsing phase: Initial syntax analysis
2. Binding phase: Symbol resolution and scoping
3. Type checking phase: Final validation
The error is caught early to avoid:
- Expensive duplicate checking later
- Confusing error messages from cascading issues
- Runtime type coercion problems
### Migration from JavaScript
When migrating JavaScript code to TypeScript:
1. Run TypeScript with --allowJs --checkJs first
2. Fix duplicate parameter errors early
3. Use // @ts-ignore sparingly with comments
4. Gradually increase strictness
### Related TypeScript Errors
- TS2300: Duplicate identifier
- TS2451: Cannot redeclare block-scoped variable
- TS2717: Subsequent property declarations must have the same type
Understanding these related errors helps diagnose complex naming issues.
Type parameter 'X' is not used in the function signature
How to fix "Type parameter not used in function signature" in TypeScript
Type parameter 'X' is defined but never used
How to fix "Type parameter is defined but never used" in TypeScript
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript