What is TS2345?
TS2345 occurs when you call a function with an argument that doesn't match the expected parameter type. This error is similar to TS2322, but specifically applies to function calls.
// Example of TS2345 error function greet(name: string): void { console.log(`Hello, ${name}!`); } greet(123); // Error: Argument of type 'number' is not assignable to parameter of type 'string'
Common Causes
1. Wrong Primitive Type
function calculateAge(birthYear: number): number { return 2024 - birthYear; } // โ Wrong - passing string instead of number calculateAge("1990"); // Error! // โ Correct calculateAge(1990);
2. Missing Properties in Object Argument
interface User { id: number; name: string; email: string; } function createUser(user: User): void { console.log(user); } // โ Missing 'email' property createUser({ id: 1, name: "John" }); // Error! // โ All properties included createUser({ id: 1, name: "John", email: "john@example.com" });
3. Null or Undefined Issues
function processName(name: string): string { return name.toUpperCase(); } const userName: string | null = getUserName(); // โ userName might be null processName(userName); // Error! // โ Check for null first if (userName !== null) { processName(userName); } // โ Or provide default processName(userName ?? "Guest");
4. Array Type Mismatch
function sumNumbers(numbers: number[]): number { return numbers.reduce((a, b) => a + b, 0); } // โ Mixed array sumNumbers([1, 2, "3", 4]); // Error! // โ Correct sumNumbers([1, 2, 3, 4]);
5. Generic Type Mismatch
function getFirst<T>(arr: T[]): T { return arr[0]; } const result: string = getFirst([1, 2, 3]); // Error! // Type 'number' is not assignable to type 'string' // โ Correct const result: number = getFirst([1, 2, 3]); // Or const result: string = getFirst(["a", "b", "c"]);
Solutions
1. Fix the Argument Type
// Convert or provide correct type const yearStr = "1990"; calculateAge(parseInt(yearStr, 10)); // Convert to number
2. Update Function Parameter Type
// Accept multiple types with union function processId(id: string | number): void { console.log(id); } processId("abc"); // OK processId(123); // OK
3. Use Optional Properties
interface User { id: number; name: string; email?: string; // Optional } function createUser(user: User): void { } createUser({ id: 1, name: "John" }); // OK now
4. Handle Null/Undefined
// Non-null assertion (use carefully) processName(userName!); // Assert non-null // Default value processName(userName || "Default"); // Nullish coalescing processName(userName ?? "Default");
5. Use Partial for Optional Properties
interface User { id: number; name: string; email: string; } // All properties become optional function updateUser(updates: Partial<User>): void { } updateUser({ name: "New Name" }); // OK
๐ก Pro Tip
When working with API responses, use type guards or validation libraries like Zod to ensure data matches expected types before passing to functions.
Real-World Examples
React Event Handlers
// โ Wrong event type const handleClick = (e: MouseEvent) => { }; <button onClick={handleClick}>Click</button> // Error! // โ Use React's event type const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => { }; <button onClick={handleClick}>Click</button> // OK
Array Methods
const numbers = [1, 2, 3, 4, 5]; // โ Callback returns wrong type const doubled: number[] = numbers.map(n => n.toString()); // Error! // โ Correct const doubled: number[] = numbers.map(n => n * 2); const strings: string[] = numbers.map(n => n.toString());
Promise/Async Functions
async function fetchUser(id: number): Promise<User> { // ... } // โ Passing string instead of number fetchUser("123"); // Error! // โ Correct fetchUser(123); fetchUser(parseInt(userId, 10));
โ ๏ธ Common Mistake
Don't use type assertions (as Type) to silence TS2345 errors. This bypasses type checking and can cause runtime errors. Fix the actual type mismatch instead.
Summary
- TS2345 occurs when function arguments don't match parameter types
- Check if you're passing the correct type
- Handle null/undefined before passing to functions
- Use union types when multiple types are valid
- Use Partial<T> for optional object properties
- Convert types explicitly when needed