TypeScript’s type system is at the heart of the book’s teachings. It allows you to catch errors at compile - time rather than runtime. For example, you can define types for variables, functions, and objects.
// Define a type for a person object
type Person = {
name: string;
age: number;
};
// Create an instance of the Person type
const person: Person = {
name: 'John',
age: 30
};
TypeScript has powerful type inference capabilities. It can automatically determine the type of a variable based on its initial value.
// TypeScript infers the type of message as string
let message = 'Hello, TypeScript!';
Interfaces and types are used to define custom types in TypeScript. Interfaces are mainly used for object shapes, while types can represent a wider range of things, including primitive types, unions, and intersections.
// Interface example
interface Animal {
name: string;
makeSound(): void;
}
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound() {
console.log('Woof!');
}
}
// Type example
type Point = {
x: number;
y: number;
};
Generics allow you to create reusable components that can work with different types. For example, a generic function to return an array of any type:
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>('myString');
let output2 = identity<number>(100);
Type assertion is used when you know the type of a value better than TypeScript does. It’s like telling TypeScript “trust me, this is the type”.
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
Union types allow a variable to have one of several types.
function printId(id: number | string) {
if (typeof id === 'number') {
console.log(`Your ID is ${id}`);
} else {
console.log(`Your ID string is ${id}`);
}
}
printId(101);
printId('abc123');
Type guards are expressions that perform a runtime check that guarantees the type in a certain scope.
function isNumber(x: number | string): x is number {
return typeof x === 'number';
}
function processValue(val: number | string) {
if (isNumber(val)) {
// Inside this block, TypeScript knows val is a number
console.log(val.toFixed(2));
} else {
console.log(val.toUpperCase());
}
}
By explicitly specifying the types of function parameters and return values, you can make your code more self - documenting and catch potential errors early.
function add(a: number, b: number): number {
return a + b;
}
any
TypeThe any
type should be used sparingly. It bypasses the type checking mechanism of TypeScript. For example, instead of:
let data: any = { value: 10 };
Try to define a proper type:
type Data = {
value: number;
};
let data: Data = { value: 10 };
Enums are useful for representing a set of named constants.
enum Color {
Red,
Green,
Blue
}
let myColor: Color = Color.Green;
When creating a public API, using interfaces makes it clear what the expected shape of an object is. It also allows for easy extension through declaration merging.
// Public API interface
interface UserAPI {
id: number;
name: string;
email: string;
}
function getUserInfo(user: UserAPI) {
return `User ${user.name} with ID ${user.id} has email ${user.email}`;
}
Enabling strict mode in TypeScript ("strict": true
in tsconfig.json
) forces you to write more type - safe code. It includes features like noImplicitAny
, strictNullChecks
, etc., which can catch many potential bugs.
{
"compilerOptions": {
"strict": true
}
}
Create functions and classes that are easy to reuse. For example, a generic utility function for validating input:
function validateInput<T>(input: T, validator: (value: T) => boolean): boolean {
return validator(input);
}
const isNumber = (value: any): value is number => typeof value === 'number';
let num = 10;
let isValid = validateInput(num, isNumber);
“Effective TypeScript” provides a wealth of knowledge and practical tips to help developers write high - quality, maintainable, and reliable TypeScript code. By understanding the fundamental concepts, mastering the usage methods, and adopting common and best practices, you can take full advantage of TypeScript’s capabilities. Whether you are a beginner or an experienced developer, the strategies presented in the book can significantly improve your TypeScript coding skills and enhance the overall quality of your projects.