Optional Properties & Interfaces

The Course
•
5 min read

Some fields are genuinely optional. note?: string means a note can be absent. Reading it gives string or undefined, so calling a string method immediately is unsafe. A required field with an empty string is a different model: the field exists, but contains no text.

Use a fallback when absence has an obvious display meaning. JavaScript’s nullish coalescing operator ?? selects the right-hand value only when the left is null or undefined. It preserves 0, false, and empty strings. Unlike ||, it does not treat every falsy value as missing.

This course enables exactOptionalPropertyTypes. An optional string property may be omitted, but assigning an explicit undefined is not the same contract. For now, omit absent fields instead of creating them with undefined. Day 3 will introduce the union syntax for deliberately allowing multiple types; you do not need it to finish today’s exercises.

An interface is another way to name an object shape: interface Session { topic: string; minutes: number }. Both an interface and a type alias can describe these records. We use type aliases consistently in the remaining beginner lessons, especially when introducing unions. For the flat records here, either spelling works. Use type aliases for the rest of this course; more interface features can wait.

Avoid turning required fields into optional ones just to silence an error. Ask whether the rest of the program can do its job without the value. A missing topic probably requires rejection; an absent note can safely display a fallback.

Predict, check, then run

Before running, write down the output and explain which information the checker knows. Click Check types first, then Check & run.

Predict, then runTypeScript
interface Session {
  topic: string;
  note?: string;
}

function describe(session: Session): string {
  return `${session.topic}: ${session.note ?? "No note"}`;
}

console.log(describe({ topic: "Objects" }));
console.log(describe({ topic: "Types", note: "" }));

Enable JavaScript to edit and type-check this example.

Check your prediction
Objects: No note
Types:

Read a real compiler error

This editor distinguishes an omitted property from one explicitly set to undefined. Read the suggested type change, then decide whether the data really needs it.

Find and fix the type errorTypeScript
type Session = {
  topic: string;

  note?: string;
};

const session: Session = { topic: "Types", note: undefined };

console.log(session.note);

Enable JavaScript to edit and type-check this example.

Check your diagnosis

For an absent note, remove the note property. If the contract intentionally permits an explicit undefined, declare note?: string | undefined. The vertical bar describes alternatives; Day 3 explains unions in detail.

Absence and empty text require different policies

An optional field can be absent. When read, its value may therefore be undefined. A present empty string is different data. Decide whether empty text means a deliberate blank or should be treated as missing before choosing a fallback expression.

With this course’s exact optional-property checking, omitting a field is different from explicitly assigning undefined to a field whose declared value type is string. You can read a missing field as undefined without making every explicit undefined assignment valid.

Absence and empty text require different policies: traceTypeScript
interface Book {
  title: string;
  note?: string;
}

function label(book: Book): string {
  return book.note ?? "No note";
}

console.log(label({ title: "Types" }));
console.log(label({ title: "Types", note: "" }) === "");

Enable JavaScript to edit and type-check this example.

Check your prediction
No note
true

The fallback handles absence and preserves deliberately empty text. Replacing ?? with || would merge these two cases, which might or might not match the intended interface policy.

Absence and empty text require different policies: contrastTypeScript
interface Book {
  title: string;
  note?: string;
}

const omitted: Book = { title: "Types" };
const present: Book = { title: "Types", note: "Review" };

console.log("note" in omitted);
console.log("note" in present);
console.log(omitted.note === undefined);

Enable JavaScript to edit and type-check this example.

Check your prediction
false
true
true

Presence is a property-level question. A read can return undefined when the field is absent; that does not mean the object contains an explicitly assigned note property.

Try the rule on new inputs

Test omitted, empty and nonempty notes. Then try the intentional assignment note:undefined and inspect the compiler rule before restoring it. State whether your formatter preserves a deliberate empty note.

Your turn

Exercise

Optional Properties & Interfaces: practise

Define a Course record with title:string and optional subtitle:string. Write caption returning the subtitle when present, otherwise “Introduction”. An empty subtitle must stay empty. Print Introduction and then Advanced practice for two examples.

Your workspaceTypeScript
// Define Course and caption. Test both an absent and a present subtitle.

Enable JavaScript to edit and type-check this example.

Hint 1: the idea

The fallback should apply to absence rather than every falsy value.

Hint 2: a first step

Read course.subtitle and combine it with a nullish fallback.

Show one solution
One possible solutionTypeScript
type Course = {
  title: string;

  subtitle?: string;
};

function caption(course: Course): string {
  return course.subtitle ?? "Introduction";
}

console.log(caption({ title: "Types" }));
console.log(caption({ title: "Types", subtitle: "Advanced practice" }));

Enable JavaScript to edit and type-check this example.

Introduction
Advanced practice

Explain the types at the function boundary and the runtime checks, if any. Compare your approach before copying this answer.

Change it and explain it

Test subtitle="" and explain why it differs from a missing subtitle. Replace the alias with an equivalent interface without changing behavior. Finally try assigning subtitle:undefined and explain this course’s exact optional-property rule.

Was this article helpful?

Your response is saved on this device.