Question

How to Create an Object from an Interface in TypeScript

Question

I have defined a TypeScript interface like this:

interface IModal {
  content: string;
  form: string;
  href: string;
  $form: JQuery;
  $message: JQuery;
  $modal: JQuery;
  $submits: JQuery;
}

Then I declare a variable like this:

let modal: IModal;

However, when I try to assign a property such as modal.content, I get an error similar to:

Cannot set property 'content' of undefined

Is it valid to use an interface to describe my modal object, and if so, how should I actually create and initialize the object?

Short Answer

By the end of this page, you will understand what a TypeScript interface does, why let modal: IModal; does not create an object, and how to properly initialize an object that matches an interface. You will also see common patterns for object creation, optional properties, and safer ways to avoid undefined errors.

Concept

A TypeScript interface describes the shape of an object. It tells TypeScript what properties an object should have and what types those properties must use.

For example:

interface IModal {
  content: string;
  form: string;
  href: string;
  $form: JQuery;
  $message: JQuery;
  $modal: JQuery;
  $submits: JQuery;
}

This does not create an object. It only defines a contract.

When you write:

let modal: IModal;

you are only declaring a variable that is expected to hold an object matching IModal later. At that moment, modal is still undefined.

So if you do this next:

modal.content = "Hello";

JavaScript tries to access the content property on undefined, which causes the runtime error.

Why this matters

In real programs, interfaces help you:

  • document object structure clearly
  • catch type mistakes during development
  • improve autocomplete and editor support
  • make function parameters and return values safer

But interfaces exist only at compile time. They do not allocate memory or create runtime values.

The key idea

  • Interface = blueprint or contract
  • Object literal / class instance / factory function = actual object in memory

To use an interface, you must still create a real object:

let modal: IModal = {
  content: "",
  form: "",
  href: "",
  $form: $("form"),
  $message: $(".message"),
  $modal: $(".modal"),
  $submits: $("button[type='submit']")
};

Mental Model

Think of an interface like an architectural drawing for a house.

  • The drawing tells you how many rooms the house should have.
  • It does not build the house.
  • Declaring let modal: IModal; is like saying, "I will have a house that follows this plan."
  • But until the house is actually built, there is nothing to walk into.

So:

  • interface IModal { ... } = the plan
  • let modal: IModal; = a promise that a matching object will exist
  • let modal: IModal = { ... } = the actual house being built
Take Quiz

Syntax and Examples

Basic syntax

1. Define the interface

interface IModal {
  content: string;
  form: string;
  href: string;
  $form: JQuery;
  $message: JQuery;
  $modal: JQuery;
  $submits: JQuery;
}

2. Create an object that matches it

let modal: IModal = {
  content: "Modal body",
  form: "loginForm",
  href: "/login",
  $form: $("#loginForm"),
  $message: $("#message"),
  $modal: $("#myModal"),
  $submits: $("button[type='submit']")
};

Now modal is a real object, so you can safely access and update its properties:

modal.content = "Updated content";
modal.href = "/signup";

Creating first, assigning later

You can also initialize it in multiple steps, but the object must exist first:

let modal: IModal = {
  content: "",
  form: "",
  href: "",
  $form: $(""),
  $message: $(""),
  $modal: $(""),
  $submits: $("")
};

modal.content = "Welcome";
modal.form = "signupForm";

Optional properties when not all values are ready yet

If some values are not available immediately, make them optional:

interface IModal {
  content: string;
  form: string;
  href: string;
  $form?: JQuery;
  $message?: JQuery;
  $modal?: JQuery;
  $submits?: JQuery;
}

let modal: IModal = {
  content: "",
  form: "",
  href: ""
};

This allows you to create the object before all jQuery references are assigned.

Using a factory function

A common pattern is to return a properly shaped object from a function:

function createModal(): IModal {
  return {
    content: "",
    form: "",
    href: "",
    $form: $("form"),
    $message: $(".message"),
    $modal: $(".modal"),
    $submits: $("button[type='submit']")
  };
}

const modal = createModal();

This is useful when you need to build the same kind of object in several places.

Step by Step Execution

Consider this code:

interface IModal {
  content: string;
  form: string;
  href: string;
}

let modal: IModal;
modal.content = "Hello";

What happens step by step

Step 1: The interface is declared

interface IModal {
  content: string;
  form: string;
  href: string;
}

TypeScript learns that any IModal object must have three string properties.

Step 2: The variable is declared

let modal: IModal;

This creates a variable named modal, but no object is assigned to it yet.

At runtime, its value is effectively:

undefined

Step 3: A property is assigned

modal.content = "Hello";

JavaScript now tries to do this:

  • look at the value of modal
  • find its content property
  • assign "Hello"

But modal is undefined, so there is no object to update.

That causes the runtime error.

Correct version

interface IModal {
  content: string;
  form: string;
  href: string;
}

let modal: IModal = {
  content: "",
  form: "",
  href: ""
};

modal.content = "Hello";

Step-by-step for the correct version

  1. The interface defines the required properties.
  2. modal is assigned a real object with those properties.
  3. modal.content = "Hello" works because modal now points to an actual object.

Real World Use Cases

Interfaces are commonly used anywhere you want consistent object structure.

UI state objects

A modal, dropdown, or form component often has related fields grouped into one object:

interface ModalState {
  isOpen: boolean;
  title: string;
  content: string;
}

API response shapes

When fetching data from a server, interfaces describe expected fields:

interface User {
  id: number;
  name: string;
  email: string;
}

Function parameters

Interfaces help functions accept structured input safely:

interface LoginData {
  username: string;
  password: string;
}

function submitLogin(data: LoginData) {
  console.log(data.username);
}

Configuration objects

Many libraries use configuration objects, and interfaces document them clearly:

interface RequestOptions {
  method: string;
  timeout: number;
}

DOM or jQuery wrappers

Your example fits this pattern well: collecting useful references and metadata in one object for reuse across event handlers and UI logic.

Take Quiz

Real Codebase Usage

In real projects, developers rarely leave typed variables uninitialized if they plan to assign properties immediately.

Common patterns

Initialize immediately

This is the simplest and most common pattern:

const modal: IModal = {
  content: "",
  form: "",
  href: "",
  $form: $("#form"),
  $message: $("#message"),
  $modal: $("#modal"),
  $submits: $(".submit")
};

Use optional properties for delayed setup

If some values are assigned later:

interface IModal {
  content: string;
  form: string;
  href: string;
  $form?: JQuery;
}

This is useful during progressive initialization.

Use a builder or factory function

Useful when object creation logic is repeated:

function buildModal(selector: string): IModal {
  return {
    content: "",
    form: "",
    href: selector,
    $form: $(`${selector} form`),
    $message: $(`${selector} .message`),
    $modal: $(selector),
    $submits: $(`${selector} button[type='submit']`)
  };
}

Validate before use

If a value might be missing, developers often guard before accessing it:

if (modal) {
  modal.content = "Ready";
}

But in strongly typed TypeScript code, it is usually better to initialize correctly instead of relying on repeated checks.

Separate data from DOM references

In larger codebases, developers may split raw data and DOM elements into separate interfaces for clarity:

interface ModalData {
  content: string;
  form: string;
  href: string;
}

interface ModalElements {
  $form: JQuery;
  $message: JQuery;
  $modal: JQuery;
  $submits: JQuery;
}

Common Mistakes

1. Thinking an interface creates an object

Broken example:

interface IModal {
  content: string;
}

let modal: IModal;
modal.content = "Hi";

Problem:

  • modal is declared but not initialized
  • no real object exists yet

Fix:

let modal: IModal = { content: "" };

2. Declaring required properties but not providing them

Broken example:

interface IModal {
  content: string;
  form: string;
}

let modal: IModal = {
  content: "Hello"
};

Problem:

  • form is required but missing

Fix:

let modal: IModal = {
  content: "Hello",
  form: "login"
};

3. Using type assertions to silence errors unsafely

Broken example:

let modal = {} as IModal;
modal.content = "Hello";

Why this is risky:

  • it tells TypeScript to trust you
  • missing properties may still cause bugs later

Better:

let modal: IModal = {
  content: "",
  form: "",
  href: "",
  $form: $(""),
  $message: $(""),
  $modal: $(""),
  $submits: $("")
};

4. Forgetting that optional properties may still be undefined

interface IModal {
  content: string;
  $form?: JQuery;
}

If $form is optional, this may be unsafe:

modal.$form.hide();

Safer:

modal.$form?.hide();

5. Mixing compile-time safety with runtime behavior

TypeScript can check shapes during development, but it does not magically initialize variables at runtime. You still need normal JavaScript object creation.

Comparisons

ConceptWhat it doesCreates a runtime object?Best use
interfaceDescribes object shapeNoDefining contracts for objects
typeDescribes a type, often similar to an interfaceNoFlexible type composition
Object literalCreates an actual objectYesSimple object creation
classDefines a blueprint for instances with behaviorYes, when instantiated with newObjects with methods and reusable behavior

Interface vs class

interface IModal {
  content: string;
}

class Modal implements IModal {
  content: string;

  constructor() {
    this.content = "";
  }
}

const modal = new Modal();
  • Use an interface when you only need to describe shape.
  • Use a class when you need methods, constructors, or object behavior.

Interface vs type alias

type Modal = {
  content: string;
  form: string;
};

For simple object shapes, interface and type are often similar. In many codebases, interface is preferred for object contracts and type is used more for unions or composed types.

Declared variable vs initialized variable

CodeResult
let modal: IModal;Variable exists, value is undefined
let modal: IModal = { ... };Variable holds a real object
Take Quiz

Cheat Sheet

interface IModal {
  content: string;
  form: string;
  href: string;
  $form: JQuery;
  $message: JQuery;
  $modal: JQuery;
  $submits: JQuery;
}

Key rule

An interface defines shape only. It does not create an object.

Wrong

let modal: IModal;
modal.content = "Hello"; // runtime error

Right

let modal: IModal = {
  content: "",
  form: "",
  href: "",
  $form: $("#form"),
  $message: $("#message"),
  $modal: $("#modal"),
  $submits: $(".submit")
};

Optional properties

interface IModal {
  content: string;
  $form?: JQuery;
}

Factory function

function createModal(): IModal {
  return {
    content: "",
    form: "",
    href: "",
    $form: $("#form"),
    $message: $("#message"),
    $modal: $("#modal"),
    $submits: $(".submit")
  };
}

Remember

  • interface = contract
  • object literal = actual value
  • required properties must be present
  • optional properties may be undefined
  • TypeScript checks types, but JavaScript still controls runtime behavior

FAQ

Does a TypeScript interface create an object?

No. An interface only describes the required structure of an object.

Why is let modal: IModal; undefined?

Because it declares the variable type but does not assign any actual object to it.

How do I create an object that matches an interface?

Assign an object literal, return one from a function, or create a class instance that matches the interface.

Can I assign properties later instead of all at once?

Yes, but the object itself must exist first. If some properties are not ready yet, make them optional or provide placeholder values.

Should I use an interface for a modal object?

Yes. It is a good use case if you want a clear, typed structure for related modal properties.

Is {} as IModal a good solution?

Usually not for beginners. It bypasses useful safety checks and can hide missing-property bugs.

When should I use a class instead of an interface?

Use a class if you need constructors, methods, or reusable behavior. Use an interface when you only need to describe object shape.

Take Quiz

Mini Project

Description

Build a small typed modal configuration object in TypeScript. This project demonstrates the main lesson from the question: an interface defines the expected structure, but you must still create a real object before using its properties. It also shows how to update the object safely after initialization.

Goal

Create and use a modal object that follows an interface without causing undefined property errors.

Requirements

  1. Define an interface for a modal object with at least content, form, and href.
  2. Create a real object that matches the interface.
  3. Update the object after creation.
  4. Add a function that prints modal information.
  5. Avoid any access on an uninitialized variable.
Take Quiz

Keep learning

Related questions

View more