RecipesChapter 5: Conditional Types

Inferring Types in Conditionals

Recipe 5.5 from The TypeScript Cookbook

class Serializer {
  constructor() {}
  serialize<T>(obj: T): Serialize<T> {
    if (
      // is an object
      typeof obj === "object" &&
      // not null
      obj &&
      // serialize is available
      "serialize" in obj &&
      // and a function
      typeof obj.serialize === "function"
    ) {
      return obj.serialize();
    }

    const ret: Record<string, any> = {};

    for (let k in obj) {
      if (typeof obj[k] === "object") {
        ret[k] = this.serialize(obj[k]);
      } else if (typeof obj[k] !== "function") {
        ret[k] = obj[k];
      }
    }
    return ret as Serialize<T>;
  }
}
Open in TypeScript Playground →