Using TypeScript first means writing code with clear types from the start. This helps catch mistakes early and makes your code easier to understand and maintain.
TypeScript-first philosophy in NestJS
class User {
id: number;
name: string;
email?: string; // optional
constructor(id: number, name: string, email?: string) {
this.id = id;
this.name = name;
this.email = email;
}
}TypeScript uses : to declare the type of a variable or property.
The ? after a property name means it is optional.
let count: number = 5; let message: string = 'Hello'; let isActive: boolean = true;
function greet(name: string): string {
return `Hello, ${name}!`;
}interface Product {
id: number;
title: string;
price: number;
}
const product: Product = { id: 1, title: 'Book', price: 9.99 };This NestJS controller uses TypeScript types to define the User shape. The getUsers method returns an array of users with clear types, helping catch errors and improving code clarity.
import { Controller, Get } from '@nestjs/common'; interface User { id: number; name: string; email?: string; } @Controller('users') export class UsersController { @Get() getUsers(): User[] { return [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob' } // email is optional ]; } }
TypeScript-first means you write types before or as you write your code, not after.
Using TypeScript with NestJS improves developer experience with better auto-completion and error checking.
Always keep your types updated as your code changes to avoid confusion.
TypeScript-first helps catch errors early by using types.
It makes your code easier to read and maintain.
NestJS is built to work well with TypeScript-first philosophy.
Practice
TypeScript-first philosophy in NestJS?Solution
Step 1: Understand TypeScript's role
TypeScript adds types to JavaScript, which helps find mistakes before running the code.Step 2: Connect to NestJS philosophy
NestJS uses TypeScript-first to improve code safety and clarity by leveraging types.Final Answer:
It helps catch errors early by using types. -> Option CQuick Check:
TypeScript-first = catch errors early [OK]
- Thinking it makes runtime faster
- Believing it removes need for tests
- Assuming it means no types needed
Solution
Step 1: Check method return type
TypeScript-first means explicitly typing the return value, herePromise<User>.Step 2: Compare options
async getUser(): Promise<User> { return this.userService.find(); } uses correct typing; others omit or use wrong types likeanyorstring.Final Answer:
async getUser(): Promise<User> { return this.userService.find(); } -> Option AQuick Check:
Explicit return type = async getUser(): Promise<User> { return this.userService.find(); } [OK]
- Omitting return type annotation
- Using 'any' instead of specific types
- Using wrong return types like string
async findUser(id: number): Promise {
const user = await this.userRepository.findOneBy({ id });
return user ?? null;
}What is the type of the value returned when no user is found?
Solution
Step 1: Analyze return statement
The method returnsuser ?? null, which means ifuseris nullish, returnnull.Step 2: Understand nullish coalescing
IffindOneByreturnsundefined, the expression returnsnullexplicitly.Final Answer:
null -> Option DQuick Check:
Nullish coalescing returns null if no user [OK]
- Assuming undefined is returned
- Thinking an error is thrown
- Expecting empty object instead of null
@Get(':id')
async getUser(@Param('id') id: string): Promise<User> {
return this.userService.findUser(id);
}Solution
Step 1: Check return type correctness
IffindUsercan returnnullwhen user not found, the controller must reflect that in its return type.Step 2: Compare options
The return type should bePromiseif user might not exist. correctly points out the return type should allownull. The parameteridshould be typed asnumbernotstring. is not always true because id can be string if parsed later.Final Answer:
The return type should be Promise if user might not exist. -> Option BQuick Check:
Return type must match possible null values [OK]
- Ignoring possible null return
- Thinking async keyword is wrong here
- Assuming @Get needs path always
name string and an optional age number using TypeScript-first philosophy. Which of these is the best TypeScript definition?Solution
Step 1: Identify required and optional properties
Thenamemust be required (no question mark),ageoptional (with question mark).Step 2: Match with options
export class CreateUserDto { name: string; age?: number; } correctly definesnameas required andageas optional in a class, which is standard for NestJS DTOs.Final Answer:
export class CreateUserDto { name: string; age?: number; } -> Option AQuick Check:
Required name, optional age = export class CreateUserDto { name: string; age?: number; } [OK]
- Marking required fields as optional
- Using interface instead of class for DTO
- Making optional fields required
Ready to prove it?
Pass the test and this pattern moves unknown
