In short
TypeScript is a statically typed superset of JavaScript: it adds types, interfaces, generics, enums and decorators, and compiles ("transpiles") down to plain JavaScript that any browser or Node.js runtime can execute. Angular is Google's full, opinionated front-end framework written in TypeScript — it ships its own component model, dependency injection, router, HTTP client, forms engine and build toolchain, so a team does not assemble these from third-party libraries. The pair matters because large enterprise applications need compile-time safety and a consistent structure across many developers, which is exactly why Indian IT services and product firms (TCS, Infosys, Wipro, Accenture, Cognizant, Capgemini, HCLTech, Zoho, Freshworks, banks and insurers) list "Angular with TypeScript" on most full-stack and UI job descriptions. In university exams (MCA web technology / enterprise application development papers) it appears as component architecture, data binding types, directives, services and DI, routing and forms; in placement rounds it appears as live coding plus questions on strict typing, observables, change detection and lifecycle order. GATE DA/CS does not examine Angular, so for MCA the weight is university practicals, project work and interviews.
Explained
TypeScript language essentials
- Why it exists: JavaScript is dynamically typed, so a typo or wrong shape fails only at runtime. TypeScript checks at compile time; the output
.jscarries no type information (types are erased). - Primitive and special types:
string,number(one numeric type — no int/float split),bigint,boolean,null,undefined,symbol, plusany(opt out of checking),unknown(safe any — must be narrowed before use),never(never returns),void. - Type annotation and inference:
let n: number = 5;is annotated;let n = 5;infersnumber. Prefer inference for locals, explicit types on function signatures and public APIs. - Interface vs type alias:
interface Student { roll: number; name: string; cgpa?: number; }—?marks optional,readonlymarks immutable. Interfaces can be *re-opened* (declaration merging) and extended; atypealias cannot be re-opened but can express unions, intersections, tuples and mapped types. Both work for object shapes. - Union, intersection, literal types:
type Status = 'PASS' | 'FAIL' | 'ABSENT';(literal union acts like a safe enum),A & Bcombines members. Narrowing viatypeof,instanceof,in, or a discriminant field drives exhaustiveswitch. - Enums:
enum Grade { A = 10, B = 8 }— numeric by default, string enums allowed;const enumis inlined. Modern style often prefers literal unions because enums emit extra JavaScript. - Functions: optional (
x?: number), default and rest (...args: number[]) parameters; overload signatures;=>arrow functions keep the lexicalthis. - Generics:
function first<T>(a: T[]): T | undefined { return a[0]; }; constraints withextends(<T extends { id: number }>); generic classes and interfaces — the backbone of Angular's typedHttpClientand RxJS operators. - Classes and OOP:
class,extends,implements,abstract, access modifierspublic | private | protected,readonly,static, getters/setters, and parameter properties —constructor(private http: HttpClient) {}declares and assigns the field in one line (used in nearly every Angular service). - Advanced/utility types examined in interviews:
Partial<T>,Required<T>,Readonly<T>,Pick<T,K>,Omit<T,K>,Record<K,V>,ReturnType<F>;keyof,typeof, indexed accessT['field'], conditional types, mapped types, template literal types; decorators (TC39 standard decorators now, Angular historically used the experimental form). - Modules and compiler: ES modules (
export/import), path aliases,tscdriven by tsconfig.json — key flagstarget,module,lib,strict(turns onstrictNullChecks,noImplicitAny,strictPropertyInitialization, etc.),sourceMap,outDir,esModuleInterop,paths. Strict mode is the default in new Angular projects; non-null assertion!and optional chaining?./ nullish coalescing??manage nullable values. - Limitation: types are compile-time only — they cannot validate data arriving from a REST API at runtime; that needs manual checks or a validator library. TypeScript's type system is also deliberately unsound in places (
any, type assertionsas, array index access).
Angular architecture and building blocks
- Component: the unit of UI — a TypeScript class decorated with
@Componentholding a selector, a template (HTML) and styles. Angular applications are a tree of components with a single root bootstrapped intoindex.html. - Template syntax (four binding forms):
- Interpolation — double curly braces around an expression, for text output.
- Property binding —
[src]="imageUrl", one-way from class to DOM. - Event binding —
(click)="save()", one-way from DOM to class, with$event. - Two-way binding —
[(ngModel)]="name"("banana in a box"), which is property + event binding combined.
- Directives: classes that change the DOM. Structural (
*ngIf,*ngFor,*ngSwitch) add or remove elements; attribute (ngClass,ngStyle, custom@Directive) change appearance or behaviour; components are directives with a template. Modern Angular replaces these with built-in control flow blocks@if,@for(with a mandatorytrackexpression) and@switch, which are faster and need no import. - Pipes: transform values in templates —
date,currency,uppercase,json,number,percent,slice,keyvalue, and the crucialasyncpipe which subscribes to an Observable or Promise and unsubscribes automatically. Custom pipes implementPipeTransform; pipes are pure by default (re-run only when the input reference changes). For Indian formatting, register theen-INlocale and use the currency codeINRso amounts render as ₹ with the lakh/crore grouping. - Services and dependency injection: reusable logic (HTTP calls, state, logging) goes in a class decorated
@Injectable({ providedIn: 'root' }), which makes it a tree-shakable application-wide singleton. Angular's hierarchical injector resolves constructor parameters by type; the modern alternative is theinject()function. Provider kinds:useClass,useValue,useFactory,useExisting, plusInjectionTokenfor non-class values. - Modules vs standalone: classically every piece was declared in an
@NgModule(declarations,imports,providers,exports,bootstrap). Since Angular 14–15, standalone components import their own dependencies directly and are the default in new projects (ng newscaffolds standalone, bootstrapped viabootstrapApplication). Exams still ask NgModule metadata, so know both. - Lifecycle hooks in order:
constructor→ngOnChanges(on every input change) →ngOnInit(once, after first inputs) →ngDoCheck→ngAfterContentInit/ngAfterContentChecked→ngAfterViewInit/ngAfterViewChecked→ngOnDestroy. Rule: constructor for injection only;ngOnInitfor initial data fetching;ngOnDestroyto unsubscribe and clear timers. - Component communication: parent → child with
@Input(), child → parent with@Output()+EventEmitter;@ViewChild/@ContentChildfor element or child-component references; a shared service with aSubject/BehaviorSubjector signals for sibling and cross-tree communication; content projection withng-content. - View encapsulation: component styles are scoped by default (
Emulated— Angular rewrites selectors with attributes); options areShadowDomandNone.
Change detection, RxJS and signals
- Change detection: after any event, Angular walks the component tree and compares each template binding's current value with the previous one, updating the DOM where they differ. Historically zone.js monkey-patches browser async APIs (events, timers, XHR) to know when to run this.
- Strategies:
Defaultchecks every component on every cycle;ChangeDetectionStrategy.OnPushchecks a component only when an@Inputreference changes, an event fires inside it, anasyncpipe emits, ormarkForCheck()is called — the standard performance fix for large screens.ExpressionChangedAfterItHasBeenCheckedErrorin dev mode means a binding mutated during change detection. - RxJS observables: Angular's async primitive. An Observable is a lazy stream of 0..n values; nothing happens until
subscribe(). Compare with a Promise: single value, eager, not cancellable.- Creation:
of,from,interval,fromEvent,throwError; subjects:Subject,BehaviorSubject(holds current value),ReplaySubject,AsyncSubject. - Operators (piped):
map,filter,tap,switchMap(cancels the previous inner request — correct for type-ahead search),mergeMap,concatMap,exhaustMap,debounceTime,distinctUntilChanged,catchError,retry,takeUntil,combineLatest,forkJoin(parallel calls, all complete),shareReplay. - Unsubscription is the classic leak source: use the
asyncpipe,takeUntilDestroyed(), ortakeUntil(destroy$);HttpClientobservables complete on their own after one response.
- Creation:
- Signals (Angular 16+, stable and recommended since 17–19): fine-grained reactive values —
signal(0), read ascount(), write withset/update;computed()derives lazily and memoises;effect()runs side effects. Inputs/outputs can be signal-based (input(),output(),model()), andtoSignal/toObservablebridge RxJS. Signals enable zoneless change detection (developer preview from Angular 18, progressing in later versions — check the version's docs) by telling Angular exactly which views are dirty.
HTTP, routing, forms
- HttpClient: injected from
provideHttpClient();http.get<Student[]>(url)returns a typed Observable; methodsget/post/put/patch/delete, options forparams,headers,responseType,observe: 'response'. Interceptors (functionalHttpInterceptorFn) attach JWT/auth headers, log, retry or show a loader centrally. Errors arrive asHttpErrorResponse; handle withcatchError. During development the CLI proxy configuration avoids CORS issues against a local Spring Boot or Node backend. - Routing:
provideRouter(routes)with aRoutesarray of{ path, component }; features —pathMatch: 'full', wildcard'**'for a 404 page,redirectTo, child routes with<router-outlet>, route parameters (:id, read viaActivatedRoute.paramMapor thewithComponentInputBinding()feature), query params,routerLinkandrouterLinkActive, programmaticRouter.navigate.- Guards (now plain functions):
canActivate,canActivateChild,canDeactivate(unsaved-changes prompt),canMatch,resolve(pre-fetch data). - Lazy loading:
loadComponent: () => import('./admin/admin.component').then(m => m.AdminComponent)orloadChildren— splits the bundle so the initial download stays small.
- Guards (now plain functions):
- Forms, two approaches:
- Template-driven (
FormsModule,ngModel,ngForm): quick, logic lives in HTML, good for small forms. - Reactive (
ReactiveFormsModule):FormControl,FormGroup,FormArray,FormBuilder; the model lives in TypeScript, is typed and unit-testable, supports dynamic controls andvalueChangesas an Observable — the enterprise default. - Validation: built-in
Validators.required,minLength,email,pattern,min/max; custom sync validators returnValidationErrors | null; async validators return an Observable (for example a server-side PAN or email-uniqueness check); cross-field validators sit on theFormGroup(password confirmation). States:valid/invalid,touched/untouched,dirty/pristine,pending.
- Template-driven (
Tooling, build, testing and quality
- Angular CLI:
ng new,ng generate component|service|guard|pipe,ng serve(dev server with hot reload),ng build(production by default),ng test,ng update(automated migrations between major versions),ng add. - Compilation: AOT (ahead-of-time) is the only production mode — templates are compiled during the build, so errors surface early, the Angular compiler is not shipped and startup is faster; JIT survives only in some test setups. The Ivy compiler and its successor pipeline enable tree-shaking of unused framework code. Current builds use esbuild/Vite-based tooling, with optional SSR / hydration via
@angular/ssr(the former Angular Universal) for SEO and first-paint speed. - Optimisations: lazy routes,
OnPushor signals,trackBy/trackin loops, pure pipes instead of template method calls,@deferblocks for below-the-fold content, CLI budgets that fail the build when a bundle crosses a size limit. - Testing: Karma/Jasmine historically, Jest or Web Test Runner in newer versions;
TestBedconfigures a testing module,ComponentFixtureandfixture.detectChanges()render,HttpTestingControllermocks HTTP, spies for services; end-to-end with Cypress or Playwright. - Angular vs React (asked constantly): Angular is a complete framework with TypeScript, DI, RxJS and CLI built in and a steeper learning curve; React is a library where routing, state and HTTP are chosen separately. (React's own details belong to its note.)
- Versioning: Angular ships two major releases a year (roughly May and November) with about 18 months of support per major; Angular 20 arrived in 2025 and the numbering continues — always confirm the exact current major and the matching TypeScript version in the release notes rather than assuming.
Key points
- TypeScript - typed superset of JavaScript; types are erased at compile time, so there is no runtime type checking.
- tsconfig strict - enables
noImplicitAnyandstrictNullChecks; the single biggest source of compile errors and of real bug prevention. - Interface vs type - interfaces merge and model object shapes; type aliases also express unions, tuples and mapped types.
- Generics - reusable, type-safe containers and functions;
extendsadds constraints. - Parameter property -
constructor(private svc: X) {}declares, assigns and injects in one line. - Component - class + template + styles, declared with
@Component; the application is a component tree. - Four bindings - interpolation, property
[x], event(y), two-way[(ngModel)]. - Directive types - structural (adds/removes DOM), attribute (changes appearance/behaviour), component.
- Control flow blocks -
@if,@forwithtrack,@switch,@deferreplace*ngIf/*ngForin modern Angular. - Pipes - template transformers; pure by default;
asyncpipe auto-subscribes and auto-unsubscribes. - **DI with
providedIn: 'root'** - tree-shakable singleton service resolved from the hierarchical injector. - Lifecycle order - constructor,
ngOnChanges,ngOnInit,ngDoCheck, content hooks, view hooks,ngOnDestroy. - Observable vs Promise - lazy, multi-value, cancellable, operator-rich versus eager and single-value.
- **
switchMapvsmergeMap** - switchMap cancels the previous inner stream (search box); mergeMap runs all in parallel. - OnPush - checks a component only on input reference change, internal event, async-pipe emission or explicit mark.
- Signals -
signal,computed,effect; fine-grained reactivity and the path to zoneless change detection. - Reactive forms - typed
FormGroup/FormControl/FormArrayin TypeScript, testable, with sync and async validators. - AOT + lazy loading - compile templates at build time and split routes to cut initial bundle size.
Examples
Example 1 — typed model, generic service and DI.
export interface Student { roll: number; name: string; cgpa: number; }
@Injectable({ providedIn: 'root' })
export class ApiService {
constructor(private http: HttpClient) {}
list<T>(url: string): Observable<T[]> { return this.http.get<T[]>(url); }
}
@Component({
selector: 'app-toppers',
standalone: true,
imports: [DecimalPipe],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@for (s of toppers(); track s.roll) {
<p>{ s.name } — CGPA <span [title]="s.roll.toString()">{ s.cgpa | number:'1.2-2' }</span></p>
} @empty { <p>No records</p> }`
})
export class ToppersComponent implements OnInit {
toppers = signal<Student[]>([]);
private api = inject(ApiService);
private destroyRef = inject(DestroyRef);
ngOnInit(): void {
this.api.list<Student>('/api/students')
.pipe(map(rows => rows.filter(r => r.cgpa >= 8.5)), takeUntilDestroyed(this.destroyRef))
.subscribe(rows => this.toppers.set(rows));
}
}
In a real template the two placeholder spans shown as single braces are written with Angular's double-brace interpolation; track s.roll is mandatory in @for and lets Angular reuse DOM nodes instead of rebuilding the list.
Example 2 — strict null checking catching a bug.
function fee(f?: number) { return f.toFixed(2); } // error under strict: 'f' is possibly undefined
function feeOk(f?: number) { return (f ?? 0).toFixed(2); } // compiles
console.log(feeOk(45000), feeOk()); // "45000.00" and "0.00"
Without strictNullChecks the first version compiles and throws TypeError in the browser when the field is missing from the API response.
Example 3 — type-ahead search with the right operator. A college-fee portal search box fires on every keystroke. With mergeMap, typing "ANNA" (4 keystrokes) issues 4 requests and the slowest response wins, so the box can show results for "ANN". The fix:
this.search.valueChanges.pipe(
debounceTime(300), distinctUntilChanged(),
switchMap(q => this.api.list<Student>(`/api/search?q=${q}`)),
catchError(() => of([]))
).subscribe(r => this.rows.set(r));
debounceTime(300) reduces 4 keystrokes typed within 300 ms to 1 request; switchMap cancels any in-flight request, so at most one response reaches the view and it is always the latest query's.
Example 4 — reactive form with a cross-field validator.
const form = this.fb.group({
pan: ['', [Validators.required, Validators.pattern(/^[A-Z]{5}[0-9]{4}[A-Z]$/)]],
password: ['', [Validators.required, Validators.minLength(8)]],
confirm: ['']
}, { validators: g => g.value.password === g.value.confirm ? null : { mismatch: true } });
"ABCDE1234F" passes the PAN pattern (5 letters, 4 digits, 1 letter); "ABCD1234F" fails. Note the pattern checks *format only* — statutory validity is verified server-side against the issuing authority, never in the browser.
Example 5 — bundle size and lazy loading. A production build reports: main 420 KB, admin feature 300 KB, reports feature 280 KB (uncompressed, after AOT and minification), total 1,000 KB. Eager: every user downloads 1,000 KB. After moving admin and reports to loadComponent routes, a normal student downloads 420 KB — a 58% reduction in initial payload; an admin pays the extra 300 KB only on navigating to that route. A CLI budget of maximumError: 500kb on the initial bundle fails the build if the split is later undone.
| Aspect | Template-driven forms | Reactive forms |
|---|---|---|
| Source of truth | Template (ngModel) | TypeScript class (FormGroup) |
| Module | FormsModule | ReactiveFormsModule |
| Data flow | Asynchronous | Synchronous |
| Typing | Weak | Strictly typed |
| Dynamic controls | Hard | FormArray, easy |
| Unit testing | Needs rendered DOM | Test the model directly |
| Best for | Small/simple forms | Enterprise, validated, dynamic forms |
| Aspect | Observable (RxJS) | Promise |
|---|---|---|
| Values | 0..n over time | Exactly 1 |
| Execution | Lazy, on subscribe | Eager, on creation |
| Cancellation | unsubscribe() | Not cancellable |
| Operators | map, filter, retry, debounce... | .then chaining only |
| Angular use | HttpClient, forms, router events | Interop via from(promise) |
Where it is used
- IT services and GCCs (TCS, Infosys, Wipro, HCLTech, LTIMindtree, Accenture, Cognizant, Capgemini): Angular front ends over Java Spring Boot or .NET REST APIs for banking, insurance and telecom clients — the single most common "full-stack" brief for Indian MCA freshers.
- Product and SaaS firms (Zoho, Freshworks, Zoho-style admin consoles, Druva, Infosys Finacle, Oracle and SAP partner teams): long-lived dashboards and back-office consoles where TypeScript's types and Angular's structure pay off over years.
- BFSI and fintech portals: net-banking dashboards, loan origination, KYC and claims screens, with Angular guards and JWT interceptors enforcing role-based access (details of tokens belong to the auth note).
- Government and public digital platforms: state e-governance portals, university ERPs, admission and examination systems built by NIC/empanelled vendors, where
en-INlocale, ₹ formatting and multi-language labels matter; accessibility and WCAG-aligned guidelines (GIGW for government sites) are tender requirements. - Job roles: Angular/front-end developer, full-stack (MEAN — MongoDB, Express, Angular, Node), UI engineer, SDET writing Cypress/Playwright suites; TypeScript alone is also used for Node/NestJS back ends and React codebases.
- Hybrid and desktop: Ionic (Angular-based) mobile apps, Electron desktop tools, and micro-frontends composing several Angular applications.
Interview questions
- Q: How is TypeScript different from JavaScript? A: TypeScript adds a compile-time type system, interfaces, generics, enums and decorators on top of JavaScript; it compiles to plain JavaScript and the types disappear at runtime.
- Q: When would you use an interface rather than a type alias? A: Use an interface for object/class contracts that may need extending or declaration merging; use a type alias for unions, tuples, intersections and mapped or conditional types.
- Q: What does
strictin tsconfig actually switch on? A: A family of flags includingnoImplicitAny,strictNullChecks,strictFunctionTypesandstrictPropertyInitialization, which together force explicit handling ofnull/undefinedand untyped values. - Q: Difference between
anyandunknown? A:anydisables checking entirely;unknownaccepts any value but forbids using it until you narrow or assert its type, so it is the safe choice. - Q: What is a decorator in Angular? A: A function applied with
@that attaches metadata to a class, field or parameter —@Component,@Injectable,@Input— which the Angular compiler reads to generate code. - Q: Why inject in the constructor and fetch data in
ngOnInit? A: The constructor runs before inputs are set and before the view exists, so it should only receive dependencies;ngOnInitruns once after the first inputs are bound, making it the right place for initialisation. - Q: How does Angular dependency injection find a service? A: It walks the hierarchical injector tree from the component's element injector up through parent injectors to the root, matching the token (usually the class type) against registered providers.
- Q: Explain
OnPushchange detection. A: The component is re-checked only when an input reference changes, an event originates inside it, anasyncpipe emits, or it is explicitly marked dirty — so mutating an object in place will not refresh the view. - Q:
switchMapormergeMapfor an autocomplete? A:switchMap, because it unsubscribes from the previous request when a new keystroke arrives, preventing stale or out-of-order results. - Q: How do you avoid memory leaks from subscriptions? A: Prefer the
asyncpipe, or usetakeUntilDestroyed()/takeUntil(destroy$), or unsubscribe inngOnDestroy; finite HttpClient streams complete by themselves. - Q: What do signals add over RxJS? A: Signals give synchronous, fine-grained, memoised reactive state with no subscription management, letting Angular update only the views that actually read a changed value — and enabling zoneless change detection; RxJS remains better for event streams and async composition.
- Q: Why is AOT compilation used in production? A: Templates are compiled at build time, so template errors are caught early, no compiler is shipped to the browser, bundles are smaller and rendering starts faster.
- Q: Standalone components versus NgModules? A: A standalone component declares its own template dependencies in
importsand needs no@NgModule; this is the default in current Angular, while NgModules remain for legacy codebases and some library packaging.
Common mistakes
- Treating TypeScript types as runtime validation — API responses still need checking; a wrong
ascast simply silences the compiler. - Sprinkling
any(or disablingstrict) to make builds pass, which throws away the entire benefit of the language. - Calling a method inside an interpolation or binding — it re-executes on every change-detection cycle; use a pure pipe, a
computedsignal or a pre-computed field. - Subscribing in a component without ever unsubscribing, and subscribing inside another subscription instead of using
switchMap/concatMap. - Mutating an array or object in place under
OnPushor with signals and expecting the view to refresh — replace the reference or useupdate. - Omitting
trackBy/trackin list rendering, which destroys and rebuilds DOM nodes and loses focus and scroll position. - Putting HTTP calls, business rules or state directly in components instead of injectable services, and fetching data in the constructor rather than
ngOnInit. - Mixing
FormsModuledirectives into reactive forms (or forgetting to importReactiveFormsModule/FormsModulein a standalone component), then reporting thatngModelorformGroup"does not work".
Related topics
Front-end frameworks: React basics · Back-end development with Node.js · REST APIs · Authentication and authorisation: sessions, OAuth and JWT · Spring Boot and microservices development · API design: GraphQL, gRPC and OpenAPI