TypeScript Tutorial
TypeScript Function Parameters
Annotate each parameter. Optional and default arguments fill in when the caller omits them.
Parameters are the inputs
The names in the parentheses of a definition are parameters. The values you write at the call site are arguments. TypeScript matches them in order: the first argument initializes the first parameter, the second argument the second parameter. Each parameter gets a type annotation.
A required parameter must be passed. An optional parameter may be left out. A default value stands in when the caller omits that argument. Numbers and strings are copied into the function. Objects and arrays are shared: a write to a field is visible to the caller.
Annotate each parameter
Write name: string and n: number, not a bare name. Understrict, an untyped parameter is an error. The annotation is the contract: the caller must pass that kind of value, and the body can use it as that type.
Example
function bump(n: number): void {
n = n + 1;
console.log("inside: " + n);
}
let coins: number = 10;
bump(coins);
console.log("after: " + coins);The program prints inside: 11 and after: 10. bump never sawcoins. It saw a copy of the number 10. Assigning to a number orstring parameter does not change the caller’s variable.
Optional parameters
A ? after the name marks the parameter optional. The caller may skip it. Inside the function the type includes undefined, so you check before you use the value. Optional parameters must trail: once one is optional, every parameter after it must be optional or have a default.
Example
function greet(name: string, title?: string): void {
if (title === undefined) {
console.log("hello, " + name);
return;
}
console.log("hello, " + title + " " + name);
}
greet("Ada");
greet("Ada", "Dr");First call prints hello, Ada. Second call prints hello, Dr Ada. You cannot skipname and still pass title. TypeScript fills from the right by omitting trailing arguments, not by jumping over a hole.
Open this in /typescript/try. Add a third call with only one argument, then with two. tsc will reject a call that passes a number where a string is required.
Default arguments
A default sits on the parameter list. If the caller omits that argument, the default is used. Defaults also trail. Once you give a default, every parameter after it needs a default or a ? too.
Example
function label(name: string, tag: string = "guest", seats: number = 1): void {
console.log(name + " (" + tag + "), seats: " + seats);
}
label("Rae");
label("Rae", "member");
label("Rae", "member", 3);First call fills tag and seats from the defaults. Second call overridestag and keeps seats at 1. Third call supplies every argument. A default already covers undefined, so you do not need a separate ? on that same parameter.
Objects are shared
When the parameter is an object, the function receives the same object the caller holds. Writing a field updates the caller’s value. That is how you change several fields without returning a new object. It is not a C++ reference parameter — there is no & — but the sharing is the same idea for objects.
Example
function bumpScore(player: { name: string; score: number }): void {
player.score = player.score + 1;
}
const p: { name: string; score: number } = { name: "Rin", score: 10 };
bumpScore(p);
console.log(p.name + " " + p.score);After bumpScore(p), p.score is 11. Replacing the whole parameter (player = ...) would not change p. Only writes to fields go through.
Choose required, optional, or default
| Parameter | Caller | Use when |
|---|---|---|
n: number | Must pass it | The function cannot work without it |
title?: string | May omit it | Absence is a real case you will check |
tag: string = "guest" | May omit it | A sensible fallback exists |
Returning a new value is still the cleanest way to produce a result from numbers: compute, thenreturn. Reach for a shared object when several fields must change together.
Put required parameters first. Optional and default parameters come last. Next: two functions can share a name if their call signatures differ. That is overloading.