TypeScript is the language Angular is written in and the language you write Angular applications with. TypeScript adds static types to JavaScript — it catches type mismatches, undefined access, and wrong API shapes at compile time rather than at runtime in the browser. For Angular development consuming an ASP.NET Core Web API, TypeScript interfaces that mirror server-side DTOs are the foundation of end-to-end type safety: the API contract is enforced in both the C# compiler and the TypeScript compiler.
TypeScript Essentials
// ── Type annotations ───────────────────────────────────────────────────────
let title: string = 'Hello Angular';
let viewCount: number = 42;
let isPublished: boolean = true;
let tags: string[] = ['dotnet', 'angular'];
// ── Interfaces — mirror ASP.NET Core response DTOs ────────────────────────
export interface PostDto {
id: number;
title: string;
slug: string;
body: string;
excerpt?: string; // optional (string | undefined)
isPublished: boolean;
publishedAt: string | null; // nullable DateTime → string | null in TS
createdAt: string;
author: AuthorDto;
tags: string[];
}
export interface AuthorDto {
id: number;
displayName: string;
avatarUrl: string | null;
}
export interface PagedResult { // generic — matches C# PagedResult
items: T[];
page: number;
pageSize: number;
total: number;
totalPages: number;
hasNextPage: boolean;
hasPrevPage: boolean;
}
// ── Null safety — TypeScript strict mode catches these ────────────────────
const post: PostDto | null = null;
// ❌ Error: post might be null
// const title = post.title;
// ✅ Optional chaining — safe access
const title = post?.title; // undefined if post is null
const excerpt = post?.excerpt ?? ''; // '' if excerpt is null/undefined
// ── Type aliases and union types ──────────────────────────────────────────
type ApiError = { status: number; title: string; errors?: Record };
type LoadingState = 'idle' | 'loading' | 'success' | 'error';
// ── Generics ──────────────────────────────────────────────────────────────
// Observable — the observable will emit PostDto arrays
// HttpResponse — full HTTP response wrapping a PostDto
// BehaviorSubject — can hold PostDto or null
strict: true in tsconfig.json by default — it enables strictNullChecks, noImplicitAny, and several other strictness flags. With strictNullChecks, TypeScript treats null and undefined as distinct types — you cannot accidentally pass null where a non-null value is expected. This catches an entire class of runtime errors (Cannot read property 'X' of null) at compile time. Embrace strict mode rather than fighting it — the compile errors it surfaces are real bugs caught before they reach users.PropertyNamingPolicy.CamelCase JSON setting), string | null for nullable DateTime properties (JSON DateTime serialises to ISO string), and string[] for string collections that the server always returns as non-null.string type represents all DateTime values from the API — Angular’s HttpClient deserialises JSON strings as plain strings, not as JavaScript Date objects. If you need date manipulation (sorting by date, calculating “3 days ago”), use the Angular DatePipe for display or call new Date(post.publishedAt) explicitly. Do not declare a DTO property as Date expecting automatic conversion — it will hold a string at runtime even though TypeScript thinks it is a Date, causing confusing bugs.tsconfig.json Strict Configuration
// tsconfig.json — Angular 18 default strict configuration
// {
// "compilerOptions": {
// "strict": true, // enables all strict checks
// "noImplicitOverride": true, // require 'override' keyword in subclasses
// "noPropertyAccessFromIndexSignature": true,
// "noImplicitReturns": true, // all code paths must return a value
// "noFallthroughCasesInSwitch": true,
// "esModuleInterop": true,
// "paths": { // path aliases for clean imports
// "@app/*": ["src/app/*"],
// "@models/*": ["src/app/models/*"],
// "@features/*": ["src/app/features/*"],
// "@shared/*": ["src/app/shared/*"]
// }
// }
// }
// With path aliases:
// import { PostDto } from '@models/post-dto'; // ✅ clean
// import { PostDto } from '../../../models/post-dto'; // ❌ fragile relative path
Common Mistakes
Mistake 1 — Declaring DateTime API properties as Date in TypeScript interfaces
❌ Wrong — publishedAt: Date; Angular HttpClient returns a string; type says Date; Date methods crash at runtime.
✅ Correct — publishedAt: string | null; convert explicitly with new Date(post.publishedAt) when needed.
Mistake 2 — Using any type to silence TypeScript errors
❌ Wrong — const data: any = response; data.whatever.nested.value — bypasses all type safety.
✅ Correct — define proper interfaces; use type assertions (as PostDto) only when you are certain of the type.