Bundle size considerations when using typescript

Mar 9, 2022

Intro

Tras cada nueva versión, Typescript trae nuevas características que hacen la vida del desarrollador mucho más facil.

Como por ejemplo:

  • Enums
  • Null coalescing operator
  • Optional chaining
  • Unions and Intersection Types
  • etc

Es muy tentador usar todas esas nuevas características en nuestros proyectos, pero no todo es oro lo que reluce.

No debemos olvidar que Typescript compila en Javacript. Según el tipo de target que definamos en nuestra configuración de Typescript el tiempo inicial de carga de nuestra app puede verse afectado.

Incluso usando el target de compilación más moderno, puede ser que algunas de las características no estén soportadas aún. Es aquí donde los polyfills o incluso el output the la build de Typescript nos puede dar dolores de cabeza en cuanto de bundle size y de loading time se refiere.

En las secciones siguientes podemos ver dos formas de reducir la salida de código Javascript preveniendo el uso de Enums y Class.

Enums vs Types

Examinemos el siguiente trozo de código:

export enum ExceptionTypes {
  error = 'error',
  info = 'info',
  warn = 'warn',
}

Este código Typescript producirá una salida Javascript como la siguiente:

export var ExceptionTypes;
(function (ExceptionTypes) {
  ExceptionTypes['error'] = 'error';
  ExceptionTypes['info'] = 'info';
  ExceptionTypes['warn'] = 'warn';
})(ExceptionTypes || (ExceptionTypes = {}));

Comparemos ahora la versión Typescript sin Enum

export type ExceptionTypeError = 'error';
export type ExceptionTypeInfo = 'info';
export type ExceptionTypeWarn = 'warn';
export type ExceptionTypes =
  | ExceptionTypeError
  | ExceptionTypeInfo
  | ExceptionTypeWarn;

En este caso, todo el typing se omite en la versión Javascript ⚡.

export {};

Classes vs Interfaces

Examinemos el siguiente trozo de código:

export abstract class Exception extends Error {
  abstract type: ExceptionTypes;
}
export class ErrorException extends Exception {
  public readonly type = ExceptionTypes.error;
}
export class InfoException extends Exception {
  public readonly type = ExceptionTypes.info;
}
export class WarningException extends Exception {
  public readonly type = ExceptionTypes.warn;
}

Este código Typescript producirá una salida Javascript como la siguiente:

export class Exception extends Error {}
export class ErrorException extends Exception {
  constructor() {
    super(...arguments);
    this.type = ExceptionTypes.error;
  }
}
export class InfoException extends Exception {
  constructor() {
    super(...arguments);
    this.type = ExceptionTypes.info;
  }
}
export class WarningException extends Exception {
  constructor() {
    super(...arguments);
    this.type = ExceptionTypes.warn;
  }
}

Comparemos ahora la versión Typescript sin clases usando solo interfaces:

export interface Exception extends Error {
  type: ExceptionTypes;
  message: string;
}
export interface ErrorException extends Exception {
  readonly type: ExceptionTypeError;
}

export interface InfoException extends Exception {
  readonly type: ExceptionTypeInfo;
}
export interface WarningException extends Exception {
  readonly type: ExceptionTypeWarn;
}

En este caso, todo el typing se omite en la versión Javascript ⚡.

export {};
Made with ❤ by @angelfraga

This site is made with AnalogJS and hosted by github pages .

© 2021 - 2024