Typing Function Parameters in TypeScript: A Practical Guide
Learn to annotate function parameters to catch bugs before they run. Master strict typing to ensure your API client receives valid, predictable data.

Previously in this course, we covered how to handle optional properties in interfaces. Now that we can define the shape of our data, it’s time to move that data around safely. In this lesson, we will focus on typing function parameters to ensure your logic always receives exactly what it expects.
Why Function Parameter Types Matter
In vanilla JavaScript, functions are "trusting." You define a parameter, and the caller can pass in null, undefined, a string, or an object—often leading to runtime errors like Cannot read property 'x' of undefined.
TypeScript moves this validation from the runtime to the development phase. By explicitly annotating your parameters, you transform your functions into contracts: "I require these specific inputs, or I won't run at all."
Annotating Parameters: The Syntax
To annotate a function parameter, place a colon after the parameter name, followed by the type.
TYPESCRIPT// A function that expects a string function greetUser(name: string) { console.log(CE9178">`Hello, ${name.toUpperCase()}!`); } // Valid call greetUser("Alice"); // TypeScript will flag this: Argument of type CE9178">'number' is not assignable to parameter of type CE9178">'string' greetUser(123);
Advancing the Task API Client
In our ongoing project, we need a function to create a new task. Without types, we might accidentally pass a missing ID or an incorrect status string. Let’s define an interface for our Task and use it to type our function parameters.
TYPESCRIPTinterface Task { id: number; title: string; isCompleted: boolean; } // We enforce that this function MUST receive an object matching the Task interface function addTask(newTask: Task) { console.log(CE9178">`Adding task: ${newTask.title}`); } // This is safe and predictable const myTask: Task = { id: 1, title: "Learn TypeScript", isCompleted: false }; addTask(myTask); // This will throw a compile-time error, preventing a bad API call addTask({ title: "Broken task" }); // Error: Property CE9178">'id' is missing in type CE9178">'{ title: string; }' but required in type CE9178">'Task'.
Hands-on Exercise
Modify your current Task API project. Create a function called updateTaskStatus that accepts a taskId (number) and a status (boolean).
- Create the function signature with strict parameter types.
- Attempt to call it with a string for the
taskId. Observe the TypeScript error in your IDE. - Fix the error by passing the correct types.
Common Pitfalls
- Confusing optional parameters with union types: Using
name?: stringmakes the parameter optional (it can beundefined). If you want the parameter to be required but allownull, usename: string | null. - Over-typing primitives: Don't feel forced to annotate every single parameter if the type is obvious. However, for API-facing functions (like our
addTask), explicit annotations are a best practice to avoid "silent" data corruption. - Forgetting the "any" trap: If you leave a parameter unannotated, TypeScript may infer it as
any, which effectively disables type checking for that variable. Always aim for explicit types in function signatures.
FAQ
Q: Can I use types and interfaces as parameter annotations?
A: Absolutely. You can use primitives (string, number), type aliases, or interfaces. Using interfaces for objects is preferred for readability.
Q: Does this change how the function runs in the browser? A: No. TypeScript strips these types during compilation. The final JavaScript produced will be clean, but the errors you caught during development ensure that your code doesn't crash when it reaches the user.
Q: What happens if I pass more arguments than expected?
A: TypeScript will flag this as an error. If a function is defined as (name: string), calling it as greet("Alice", 123) will result in an error: "Expected 1 arguments, but got 2."
Recap
By annotating function parameters, you act as the first line of defense against bugs. You've learned how to enforce input shapes, catch invalid calls at compile-time, and ensure your addTask function maintains the integrity of your data model.
Up next: We will explore how to define function return types to ensure the data coming out of your functions is just as safe as the data going in.
Work with me

Next.js Full-Stack Web App Development
A fast, SEO-ready full-stack web app built with Next.js 16 — from idea to deployed product, by an engineer who ships to production.

React & Next.js Dashboard / Admin UI Development
A clean, data-rich dashboard UI in React or Next.js — charts, tables, and real-time data that your users will actually enjoy using.