My TypeScript cheat-sheet

Photo by Web Donut on Unsplash

TypeScript became essential part of my professional activity. It got to the point that if I see pure JavaScript code, I simply can't acknowledge that. I immediately start asking myself "How is that possible for a language to not to have types?".

There are some tips and tricks I don't use quite often, so I decided to write down some notes, so I could always have them available.

Extend one complex type from another

I am not a huge fan of interfaces and inheritance, since there is plenty of ways to create a derivative type, via "union" and a few extra tricks:

type CarType = {
speed: number;
color: string;
model: string;
// Add a subset of properties from CarType
type PlaneTypeA = {
class: string
} & Pick<CarType, 'speed' | 'model'>;
// Add one property from CarType
type PlaneType = {
class: string;
speed: CarType["speed"];
// "Inherit" type
type SuperCarType = {
super: boolean;
} & CarType;

Typing static class methods

Not a huge sucker for OOP either, but occasionally I have to deal with it. So,

interface CommandProcessorInstance {}
export interface CommandProcessor {
new (): CommandProcessorInstance;
attach(program: CommanderCommand): void;
process(args?: CommandActionArguments): Promise<void>;
export function Implements<T>() {
return <U extends T>(constructor: U) => {
// eslint-disable-next-line no-unused-expressions
export class CommandRun {
public static attach(
program: CommanderCommand,
) {
// ...
public static async process(
args: CommandActionArguments,
) {
// ...

Indexed vs Mapped Object vs Record

type MyMappedObjectType = {
[k in string | number]: unknown;
type MyIndexedType = {
[k: string]: unknown;
type MyRecord = Record<string, unknown>;

Assign argument types

If I have multiple functions of the same signature, I don't have to specify argument types every time. Instead, I make a type declaration once and just assign it to many functions. TS is smart enough to figure argument types in this case.

type SomeFunctionType = (foo: number, bar: string, baz: boolean) => void;
const funA: SomeFunctionType = (a, b, c) => { ... };
const funB: SomeFunctionType = (a, b, c) => { ... };
const funC: SomeFunctionType = (a, b, c) => { ... };

Create types from types


It is possible to use generics to make a dependency between types of function arguments:

function pluck<T, K extends keyof T>(o: T, propertyNames: K[]): T[K][] {
return propertyNames.map((n) => o[n]);


Sometimes I can't import types from a third-party library, or I simply don't have types explicitly defined. Nevertheless, there is a way to declare a variable to be of the same type as the other variable:

const data = [
{ name: 'Alex', position: 'pilot' },
{ name: 'Amos', position: 'tech' },
const crewMember: typeof data[0] | undefined;

Pulling out the type of an element of an array

Using typeof + infer + conditional is ass-saving when it's too lazy to describe a type, or simply don't have access to library types.

const data = [
{ name: 'Alex', position: 'pilot', customField: '1' },
{ name: 'Amos', position: 'tech', otherCustomField: true },
const ElementType = typeof data extends (infer U)[] ? U : unknown;

No rest for an engineer, so, yeh, to be continued...


Sergei Gannochenko

Business-oriented fullstack engineer, in ❤️ with Tech.
React, Node, Docker, AWS, Jamstack.
15+ years in dev.