If you’re a C# developer dipping your toes into frontend development, TypeScript will feel surprisingly familiar. It’s JavaScript with types, and Microsoft designed it with C# developers in mind. Here’s what you need to know.
Why TypeScript?
JavaScript is… flexible. Too flexible sometimes. TypeScript adds compile-time type checking, which catches bugs before they hit production. If you’ve ever debugged “undefined is not a function” at 2 AM, you’ll appreciate this.
Types: What You Already Know
// Basic types - just like C#
let name: string = "John";
let age: number = 30;
let isActive: boolean = true;
let items: string[] = ["one", "two", "three"];
// Any - the escape hatch (use sparingly!)
let mystery: any = 42;
mystery = "now I'm a string";
Interfaces vs Classes
In C#, we use interfaces for contracts and classes for implementation. TypeScript is similar, but interfaces are more powerful:
// Interface - shape of an object
interface User {
id: number;
name: string;
email?: string; // Optional property
readonly createdAt: Date; // Read-only
}
// Class - with implementation
class UserService {
private apiUrl: string;
constructor(apiUrl: string) {
this.apiUrl = apiUrl;
}
async getUser(id: number): Promise<User> {
const response = await fetch(`${this.apiUrl}/users/${id}`);
return response.json();
}
}
Functions
// Typed function
function greet(name: string, greeting?: string): string {
return `${greeting || 'Hello'}, ${name}!`;
}
// Arrow functions (like C# lambdas)
const add = (a: number, b: number): number => a + b;
// Callback types
function processItems(items: string[], callback: (item: string) => void): void {
items.forEach(callback);
}
Generics
Generics work almost identically to C#:
// Generic function
function firstOrDefault<T>(items: T[], predicate: (item: T) => boolean): T | undefined {
return items.find(predicate);
}
// Generic interface
interface Repository<T> {
getById(id: number): Promise<T>;
getAll(): Promise<T[]>;
save(item: T): Promise<void>;
}
// Usage
const user = firstOrDefault(users, u => u.id === 1);
Key Differences from C#
- Structural typing: TypeScript uses duck typing. If it has the right shape, it’s compatible
- No method overloading: Use optional parameters or union types instead
- Null handling: null and undefined are different. Enable strict null checks
- Enums: Similar but with some JavaScript quirks
Recommended tsconfig.json
{
"compilerOptions": {
"target": "ES2017",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
Enable strict mode from day one. It catches so many bugs.
References
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.