Types and inference
What you annotate, what the compiler works out for itself, and why any is a hole.
After this lesson you can
- Annotate a variable, a parameter and a return type
- Say when to annotate and when to let inference do it
- Explain the difference between any and unknown
TypeScript is JavaScript with types checked before the code runs. Nothing survives to runtime: the types are erased, and what ships is JavaScript.
const name: string = "Nino";
const years: number = 5;
const remote: boolean = true;
Those annotations are all unnecessary. TypeScript already knows "Nino" is
a string. Writing the type again adds nothing and gives you a second thing
to keep in sync.
Annotate the edges
The useful rule: annotate what crosses a boundary, infer the rest.
function fullName(first: string, last: string): string {
const joined = `${first} ${last}`; // inferred as string
return joined;
}
Parameters must be annotated, because nothing tells the compiler what a caller will pass. A return type is optional but worth writing on anything exported: it makes the function's promise explicit, and it means a mistake inside the function is reported inside the function rather than at every call site.
Try it
export function describe(): string { // No annotations anywhere; TypeScript infers every one of these. const name = "Nino"; const years = 5; const skills = ["C#", "PostgreSQL"]; // skills is string[], so .join is available and .toFixed is not. return `${name}, ${years} years, ${skills.join(" and ")}`;}any and unknown
any switches the checker off for that value. Everything is allowed, and
the hole spreads: anything derived from an any is also unchecked.
unknown is the safe version. You can hold it, pass it, store it — you just
cannot use it until you have proved what it is.
function parse(raw: unknown): number {
if (typeof raw === "number") return raw; // proved
if (typeof raw === "string") return Number(raw);
throw new Error("not a number");
}
Whenever you are about to write any, unknown plus a check is almost
always what you actually wanted.
Try it yourself
2 visible tests · 2 hidden testsImplement average(nums: number[]): number that returns the mean of the
array. An empty array has no mean — return 0 rather than NaN or
throwing.
average([2,4,6])average([10])
Sign up to check the hidden tests and save your progress. Sign up