User-defined type guards in TypeScript

Decided to write this blog post because I couldn’t find any documentation or online examples like the one I’m sharing here. Every example I’ve seen the user-defined type guard is used to replace the whole type definition and not specific properties.

Here’s the code without type guard.

interface Config {
  foo: string;
  bar: string;
}

class Thing {
  name: string;
  config?: Config;

  constructor(name: string, config?: Config) {
    this.name = name;
    this.config = config;
  }

  // 👀 returning boolean, will change on next example
  hasConfig(): boolean {
    if (this.config) {
      return true;
    }
    return false;
  }
}

let firstThing = new Thing("Apple", { foo:"one", bar: "two" });

if (firstThing.hasConfig()) {
  // #1 - Here firstThing.config is `Config | undefined`
  console.log(firstThing.config.foo);
}

if (firstThing.config) {
  // #2 - Here firstThing.config is `Config`
  console.log(firstThing.config.foo);
}

On #1 firstThing.config. is Config | undefined even though we know it can’t be undefined because our hasConfig method made sure the value is truthy.

On #2 firstThing.config is Config as expected.

So in order to help TypeScript detect the correct type we can use a type predicate as the return type.

interface Config {
  foo: string;
  bar: string;
}

class Thing {
  name: string;
  config?: Config;

  constructor(name: string, config?: Config) {
    this.name = name;
    this.config = config;
  }

  // 👀 notice the return type
  hasConfig(): this is { config: Config } {
    if (this.config) {
      return true;
    }
    return false;
  }
}

let firstThing = new Thing("Apple", { foo:"one", bar: "two" });

if (firstThing.hasConfig()) {
  // Now firstThing.config is `Config`
  console.log(firstThing.config.foo);
}

Now firstThing.config is Config as expected. Have in mind that even though the type guard says this is { config: Config }, TypeScript will merge this type with the original type definition of Thing.

Thanks to the nice folks at the TypeScript Discord who helped me solve this issue. Hope this helps more people.

Published
Categorized as Default

The Scanimate

Source: YouTube

Amo este tipo de equipo análogo para video.

Aprendí editar video con equipos de esta generación y la verdad es que los extraño mucho. Recuerdo claramente el sonido de las VTR haciendo “rewind” y “pre-roll” para comenzar a grabar donde habías puesto el mark in. Recuerdo los switchers y controles de efectos.

Fue una época muy divertida y de aprender mucho.

Published
Categorized as Default

Intercept and modify requests with this browser extension

This Chrome extension will allow you to intercept and modify, request and responses made by web pages. Very cool.

My only feedback is that this should be an additional tab on the developers tool panel.

Can’t wait for this extension to come to Firefox and other privacy friendly browsers.

Link

Published
Categorized as Default

El Whistleblower

Ep 80: The Whistleblower

Otro excelente episodio de este podcast que se ha vuelto uno de mis favoritos. En Puerto Rico nos hacen falta mas “whistleblowers” y leyes que los protejan.

Link

Published
Categorized as Default

Regalos que protegen la privacidad

Mozilla: Privacy not included

Una lista de productos electrónicos que cumplen con unos estándares mínimos de privacidad. La lista de productos es creada y mantenida por Mozilla una organización que se caracteriza por ser defensores de los derechos a la privacidad de los usuarios en Internet.

Link

Published
Categorized as Default