Skip to main content

Working with HTML and DOM

Level: Beginner

ℹ️ What You'll Learn
  • Typing element selections with generics
  • HTMLElement, HTMLInputElement, HTMLFormElement types
  • Event types: MouseEvent, ChangeEvent, FormEvent
  • Event handlers and listener types
  • Form values with proper typing
  • Creating typed element creation patterns
  • Document and window type safety
  • SMS form element manipulation

Why This Matters

Working with HTML and DOM helps you write safer frontend code. In ASP.NET Core projects, TypeScript makes API response shapes, form models, DOM values, and reusable helpers easier to maintain.

Type-safe DOM manipulation in TypeScript.

The Problem

JavaScript allows many mistakes to appear only at runtime. This lesson shows how Working with HTML and DOM lets TypeScript catch wrong values, missing properties, and unsafe assumptions before the page reaches users.

Selecting Elements

// Select single element
const button = document.getElementById('submitBtn');
// Type: HTMLElement | null

// Type assertion if sure it exists
const button = document.getElementById('submitBtn') as HTMLButtonElement;

// QuerySelector (safer)
const form = document.querySelector('#studentForm') as HTMLFormElement;

// QuerySelectorAll
const inputs = document.querySelectorAll('input');
// Type: NodeListOf<Element>

Element Types

const input = document.getElementById('name') as HTMLInputElement;
input.value = "Ravi";
input.type = "text";

const button = document.getElementById('submit') as HTMLButtonElement;
button.disabled = false;
button.click();

const select = document.getElementById('className') as HTMLSelectElement;
select.value = "10";

const textarea = document.getElementById('remarks') as HTMLTextAreaElement;
textarea.value = "Good student";

Event Handlers

const form = document.getElementById('studentForm') as HTMLFormElement;

// Type the event
form.addEventListener('submit', (event: SubmitEvent) => {
event.preventDefault();
const formData = new FormData(form);
});

const button = document.getElementById('btn') as HTMLButtonElement;
button.addEventListener('click', (event: MouseEvent) => {
console.log(event.clientX, event.clientY);
});

const input = document.getElementById('search') as HTMLInputElement;
input.addEventListener('input', (event: Event) => {
const value = (event.target as HTMLInputElement).value;
});

Form Handling

const studentForm = document.getElementById('studentForm') as HTMLFormElement;

studentForm.addEventListener('submit', async (event: SubmitEvent) => {
event.preventDefault();

const formData = new FormData(studentForm);
const name = (formData.get('name') as string) || '';
const email = (formData.get('email') as string) || '';
const className = (formData.get('className') as string) || '';

const studentData = {
name,
email,
className
};

// Send to API
});

Manipulating Elements

// Get elements
const tableBody = document.querySelector('tbody') as HTMLTableSectionElement;
const countSpan = document.getElementById('studentCount') as HTMLSpanElement;

// Create element
const row = document.createElement('tr');
row.innerHTML = `
<td>101</td>
<td>Ravi Kumar</td>
<td>ravi@example.com</td>
`;

// Append
tableBody.appendChild(row);

// Update text
countSpan.textContent = '45';

// Set attributes
row.dataset.studentId = '101';
const id = row.dataset.studentId; // '101'

Type Guards

function handleInput(element: HTMLElement): void {
if (element instanceof HTMLInputElement) {
// Now TypeScript knows it's HTMLInputElement
const value = element.value;
} else if (element instanceof HTMLSelectElement) {
const value = element.value;
}
}

// Or type assertion
function getValue(element: HTMLElement): string {
const input = element as HTMLInputElement;
return input.value;
}

SMS Example

interface StudentFormData {
rollNumber: string;
name: string;
email: string;
className: string;
}

class StudentForm {
private form: HTMLFormElement;
private submitBtn: HTMLButtonElement;
private tableBody: HTMLTableSectionElement;

constructor() {
this.form = document.getElementById('studentForm') as HTMLFormElement;
this.submitBtn = this.form.querySelector('button[type="submit"]') as HTMLButtonElement;
this.tableBody = document.querySelector('tbody') as HTMLTableSectionElement;

this.setupEventListeners();
}

private setupEventListeners(): void {
this.form.addEventListener('submit', (event: SubmitEvent) => this.handleSubmit(event));
}

private handleSubmit(event: SubmitEvent): void {
event.preventDefault();

const formData = new FormData(this.form);
const data: StudentFormData = {
rollNumber: formData.get('rollNumber') as string,
name: formData.get('name') as string,
email: formData.get('email') as string,
className: formData.get('className') as string
};

this.submitBtn.disabled = true;
this.submitBtn.textContent = 'Registering...';

this.registerStudent(data);
}

private async registerStudent(data: StudentFormData): Promise<void> {
try {
const response = await fetch('/api/students', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});

if (!response.ok) throw new Error('Failed');

const result = await response.json();
alert(`Student ${result.name} registered!`);
this.form.reset();
} catch (error) {
alert('Error: ' + (error instanceof Error ? error.message : 'Unknown'));
} finally {
this.submitBtn.disabled = false;
this.submitBtn.textContent = 'Register';
}
}
}

// Initialize
new StudentForm();

Key Takeaways

  • Type HTML elements for safety
  • Use as for type assertions
  • Event handlers have specific types
  • Type guards for conditional checks
  • DOM manipulation is type-safe
  • Next: Advanced types and error handling
💡 Backend Developer Tip

Always cast elements to specific types (HTMLInputElement, HTMLButtonElement). Prevents runtime errors when accessing element properties.

⚠️ DOM Typing Mistakes
  1. Not casting elements — Accessing properties fails
  2. Wrong event type — Event object properties unavailable
  3. Forgetting null check — getElementById returns null if not found
  4. Not using type guards — Type errors with optional chaining
🤖Use AI to Learn Faster

Use ChatGPT, Claude, or Copilot to go deeper on TypeScript DOM. Try these prompts:

  • "Why cast HTML elements?"
  • "What are event types?"
  • "How do you handle form data?"
  • "Quiz me on DOM types"

💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.

Quick Definitions

  • Working with HTML and DOM - The main TypeScript concept explained in this lesson.
  • Type - A rule that describes what kind of value is allowed.
  • Interface - A contract that describes the shape of an object.
  • DTO model - The frontend shape of data coming from ASP.NET Core Web API.

Common Mistakes

  • Using any instead of defining a useful type
  • Making types too complex before understanding the data
  • Forgetting that API data still needs runtime validation
  • Confusing JavaScript runtime behavior with TypeScript compile-time checks
  • Not reusing shared types for repeated API models

Practice Task

Create a small TypeScript example using Working with HTML and DOM. Keep it connected to a School Management System scenario.

Suggested practice:

  1. Define a Student, Teacher, Attendance, or Marks model.
  2. Write one function or class using that type.
  3. Add one intentionally wrong value and read the TypeScript error.
  4. Fix the type or the data shape.
  5. Explain the type contract in your own words.

Quick Revision

QuestionAnswer
What is the main idea?Use TypeScript to make Working with HTML and DOM safer and clearer.
Where is it used?API models, forms, DOM code, helpers, and React/Next.js apps.
What should beginners avoid?Overusing any and ignoring API validation.
What is the best debugging habit?Read the TypeScript error and compare it with the expected data shape.
🎯 How would you explain Working with HTML and DOM in an interview?

Working with HTML and DOM is a TypeScript concept that improves JavaScript safety by making data shapes and function expectations clear. I would explain the problem it solves, show a small example, and mention how it helps with API-connected frontend code.

🎯 Where is this used in real projects?

It is used in API DTOs, form models, DOM access, helper functions, React props, service classes, and reusable frontend utilities.

Next Article

Type Guards and Advanced Types ->

nexcoding.in