TypeScript is a superset of JavaScript that adds static types. This addition helps catch errors during development, improving maintainability and making the codebase easier to understand at a glance. Understanding TypeScript types is crucial for developing robust applications. Here's an in-depth guide focusing on TypeScript types, their application, and how they improve the overall development experience.
Basic types in TypeScript
TypeScript typed variables: TypeScript allows you to specify a type for variables using a simple syntax. Here are the basic types:
Boolean: Represents a logical value,
true
orfalse
.Terminallet isCompleted: boolean = falseNumber: All numbers in TypeScript are floating point values. These types can represent both integers and floats.
Terminallet decimal: number = 6let hex: number = 0xf00dlet binary: number = 0b1010let octal: number = 0o744String: Represents a sequence of characters. TypeScript supports both double-quoted (
"
) and single-quoted ('
) strings, as well as template strings, which can span multiple lines and have embedded expressions.Terminallet color: string = 'blue'let fullName: string = 'Bob Bobbington'let greeting: string = `Hello, my name is ${fullName}`Array: TypeScript allows you to define an array of elements of a specific type using one of two possible syntaxes.
Terminallet list: number[] = [1, 2, 3]// or using a generic array typelet anotherList: Array<number> = [1, 2, 3]Tuple: Tuple types allow you to express an array where the type of a fixed number of elements is known, but need not be the same.
Terminallet person: [string, number] = ['Chris', 22]Enum: A way of giving more friendly names to sets of numeric values.
Terminalenum Color {Red,Green,Blue}let c: Color = Color.GreenAny: A fallback to the dynamic nature of JavaScript, allowing any type of value, with no specific type-checking applied.
Terminallet notSure: any = 4notSure = 'maybe a string instead'notSure = falseVoid: Used on function return types to signify that the function does not return a value.
Terminalfunction warnUser(): void {console.log('This is my warning message')}Null and undefined: In TypeScript, both
null
andundefined
actually have their own types namednull
andundefined
respectively.Terminallet u: undefined = undefinedlet n: null = nullNever: Represents the type of values that never occur. For functions that throw an exception or never return, such as function throwing errors.
Terminalfunction error(message: string): never {throw new Error(message)}Object: Represents any non-primitive type. Note that
object
type is different fromObject
or{}
and only allows you to assign any non-primitive types.Terminallet obj: object = { x: 0, y: 0 }
Functions in TypeScript
TypeScript function typing:
TypeScript enables you to add types to each of the parameters and the return value of a function to ensure that the correct types are passed and returned.
Example:
function add(x: number, y: number): number {return x + y}
This function clearly states that add
takes two parameters, both of which are numbers, and also returns a number.
Advanced types
Union types:
A union type allows a variable to be one of several types. The pipe (|
) is used to separate each type.
Example:
let multiType: number | stringmultiType = 20 // validmultiType = 'twenty' // valid
Intersection types:
Intersection types allow you to combine multiple types into one. This is often used for combining multiple objects into one object.
Example:
type Employee = {name: stringstartDate: Date}type Admin = {name: stringprivileges: string[]}type ElevatedEmployee = Employee & Adminlet newEmployee: ElevatedEmployee = {name: 'Alice',startDate: new Date(),privileges: ['create-server', 'access-database']}
Generics:
Generics provide a way to create reusable components. A component can handle values of various types without being type-specific.
Example:
function insertAtBeginning<T>(array: T[], value: T) {return [value, ...array]}const demoArray = [1, 2, 3]const updatedArray = insertAtBeginning(demoArray, -1) // [-1, 1, 2, 3]
Type assertions
Type assertions are like type casting in other languages but perform no special checking or restructuring of data.
Example:
let someValue: any = 'this is a string'let strLength: number = (someValue as string).length
Type guards
Type guards allow you to narrow down the type of an object within a conditional block.
Example:
function isNumber(x: any): x is number {return typeof x === 'number'}function isString(x: any): x is string {return typeof x === 'string'}function padLeft(value: string, padding: string | number) {if (isNumber(padding)) {return Array(padding + 1).join(' ') + value}if (isString(padding)) {return padding + value}throw new Error(`Expected string or number, got '${padding}'.`)}
Utility types
TypeScript provides several utility types to facilitate common type transformations. These include Partial<T>
, Readonly<T>
, Pick<T, K>
, Record<K, T>
, and more.
Example:
interface Todo {title: stringdescription: string}function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {return { ...todo, ...fieldsToUpdate }}const todo1 = {title: 'organize desk',description: 'clear clutter'}const todo2 = updateTodo(todo1, {description: 'throw out trash'})
For further reading on TypeScript types, see the official TypeScript documentation.