Data report"State of code review 2024" is now liveRead the full report

TypeScript typing

Kenny DuMez
Kenny DuMez
Graphite software engineer

TypeScript, a typed superset of JavaScript, provides advanced typing features that enable developers to write more reliable and maintainable code. This guide will explore TypeScript’s typing system, exploring different ways to define, use, and extend types, including functions, utility types, and more.

TypeScript offers several basic types which include number, string, boolean, null, undefined, symbol, and bigint. Here's a simple example:

Terminal
let isActive: boolean = false
let total: number = 150

You can define types for objects by specifying the types of their properties:

Terminal
type User = {
name: string
age: number
}
const user: User = {
name: 'John Doe',
age: 30
}

Union types allow a variable to be one of several types:

Terminal
type ID = string | number
let userId: ID = 'abc123' // Can also be a number

Here, the ID type is defined as a union type that can either be a string or a number, allowing for variable use cases where an identifier might be represented in different formats across different contexts or systems. This capability is particularly useful in web development, where user input might be dynamically typed yet still needs to conform to certain expected types, ensuring type safety without losing the versatility needed in JavaScript-based environments. Additionally, union types help in creating more robust interfaces and APIs by explicitly stating that a value can legitimately be one of several types, thereby preventing runtime errors and enhancing code maintainability.

Functions in TypeScript can be typed both in terms of the arguments they take and the values they return:

Terminal
type GreetFunction = (name: string) => string
const greet: GreetFunction = (name) => `Hello, ${name}!`

While both interface and type can be used to define types in TypeScript, there are some differences:

  • Interfaces are open and can be extended by declaring the same interface multiple times.
  • Types are closed and cannot be reopened to add new properties but can be extended using intersections.
Terminal
interface Animal {
name: string
}
interface Animal {
species: string
}
type Vehicle = {
manufacturer: string
}
// Extending types using intersections
type Car = Vehicle & {
wheels: number
}

You can extend types using intersections as shown above, or for interfaces, simply by extending them:

Terminal
interface Shape {
color: string
}
interface Circle extends Shape {
radius: number
}

TypeScript provides several utility types that are extremely useful for common type transformations:

Terminal
// Partial type makes all properties of an object type optional
type PartialUser = Partial<User>
// Readonly type makes all properties of an object type read-only
type ReadonlyUser = Readonly<User>

TypeScript doesn’t have a specific map type, but Map objects can be typed with generics:

Terminal
const map: Map<string, number> = new Map()
map.set('one', 1)

Type guards are a way to provide information about the type of a variable within a conditional block:

Terminal
function isString(test: any): test is string {
return typeof test === 'string'
}
function example(foo: any) {
if (isString(foo)) {
console.log("It's a string!", foo.toUpperCase())
} else {
console.log("It's not a string!", foo)
}
}
  1. Prefer interfaces over types when you might need to extend them.
  2. Use union types to allow for flexibility in your APIs.
  3. Utilize utility types to manipulate types easily and effectively.
  4. Implement type guards to ensure variables are of the correct type at runtime.
  5. Leverage generics to create reusable and flexible components.

For further information on TypeScript typing see the official documentation.

Git gud
"It's the first Git workflow I've used that actually feels good."
–@robboclancy
Learn more

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2