Skip to content

Instantly share code, notes, and snippets.

@rbuckton
Last active August 25, 2022 19:53
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbuckton/4b8df4908aad49aac212 to your computer and use it in GitHub Desktop.
Save rbuckton/4b8df4908aad49aac212 to your computer and use it in GitHub Desktop.
Type serialization

Intrinsics

type serialized
void undefined
string String
number Number
boolean Boolean
symbol Symbol
any Object
enum E {} Number
class C {} C

Complex Types

Complex types can be serialized using the following format:

/**
  * A type or constructor function.
  */
type Type = Function 
          | _Type;
          
/** 
  * Basic shape for a type.
  */
interface _Type {
  /** 
    * Describes the specific shape of the type.
    * @remarks 
    * One of: "typeparameter", "typereference", "interface", "tuple", "union", 
    * or "function".
    */
  kind: string; 
}

/**
  * A generic type parameter. 
  */
interface TypeParameter extends _Type {
  /**
    * An optional constraint for the type parameter.
    */
  constraint?: Type;
}

/**
  * A reference to a generic type. 
  */
interface TypeReference extends _Type {
  kind: string; // "typereference"
  
  /**
    * The referenced generic type
    */
  type: Type;
  
  /**
    * The generic type arguments, in order.
    */
  typeArguments?: Type[];
}

/**
  * Describes a generic interface.
  */
interface InterfaceType extends _Type {
  kind: string; // "interface"
  
  /**
    * Generic type parameters for the type. May be undefined.
    */
  typeParameters?: TypeParameter[];
  
  /**
    * Implemented interfaces.
    */
  implements?: Type[];
  
  /**
    * Members for the type. May be undefined. 
    * @remarks Contains property, accessor, and method declarations.
    */
  members?: { [key: string | symbol | number]: Type; };
  
  /**
    * Call signatures for the type. May be undefined.
    */
  call?: Signature[];
  
  /**
    * Construct signatures for the type. May be undefined.
    */
  construct?: Signature[];
  
  /**
    * Index signatures for the type. May be undefined.
    */
  index?: Signature[];
}

/**
  * Describes a tuple type.
  */
interface TupleType extends _Type {
  kind: string; // "tuple"
  
  /**
    * Types of each element in the tuple.
    */
  elements: Type[];
}

/**
  * Describes a union type.
  */
interface UnionType extends _Type {
  kind: string; // "union"
  
  /**
    * Types of each member of the union.
    */
  types: Type[];
}

/**
  * Describes a function type.
  */
interface FunctionType extends _Type {
  kind: string; // "function"
  
  /**
    * The signatures for the function type
    */
  signatures: Signature[];
}

/**
  * Describes a signature.
  */
interface Signature {
  /**
    * A value indicating whether this is a constructor signature.
    */
  construct?: boolean;
  
  /**
    * Generic type parameters for the function type. May be undefined.
    */
  typeParameters?: TypeParameter[];
  
  /**
    * Parameters for the function type.
    */
  parameters: Type[];
  
  /**
    * The number of required parameters of the function type.
    */
  length: number;
  
  /**
    * A value indicating whether the final argument is a rest argument. May be undefined.
    */
  rest?: boolean;
  
  /**
    * The return type of the function type.
    */
  returns: Type;
}

Interface

// type
interface Point {
  x: number;
  y: number;
}

// serialized
({ 
  kind: "interface",
  members: { 
    x: Number, 
    y: Number 
  } 
})

Open Generic Interface

// type
interface Record<T, U> {
  first: T;
  second: U;
}

// serialized
(
  _T = { kind: "typeparameter" }, 
  _U = { kind: "typeparameter" }, 
  { 
    kind: "interface"
    typeParameters: [_T, _U], 
    members: { 
      first: _T, 
      second: _U 
    } 
  }
)
...
var _T, _U;

Circular Interface

// type
interface Node { 
  prev: Node;
  next: Node;
}

// serialized
(
  _a = { 
    kind: "interface", 
    members: { }
  }, 
  _a.members.prev = _a,
  _a.members.next = _a,
  _a
)
...
var _a;

Type Reference

// type
type S = string[];

// serialized
({
  kind: "typereference",
  type: Array,
  typeArguments: [String]
})

Tuple Type

// type
type T = [number, string];

// serialized
({ 
  kind: "tuple",
  elements: [Number, String]
})

Union Type

// type
type U = number | string;

// serialized
({ 
  kind: "union",
  types: [Number, String]
})

Function Type

// type
type F = (x: number, y: string, ...z: boolean[]) => Object;

// serialized
({
  kind: "function"
  signatures: [
    {
      parameters: [
        Number,
        String,
        { kind: "typereference", type: Array, typeArguments: [Boolean] }
      ],
      length: 2,
      rest: true,
      returns: Object
    }
  ]
})

Complex Example

// type
import { X } from 'external'; // may be unknownType in single-file compile

interface Z {
  prop: string[];
}

interface I<T> extends Z {
  method<U>(x: X, y: T): U;
  [key: string]: [number, boolean];
}

// serialized
(
  _X = { kind: "typereference", type: _external.X || Object }, 
  _T = { kind: "typeparameter" },
  _U = { kind: "typeparameter" },
  _Z = { 
    kind: "interface",
    members: {
      prop: { kind: "typereference", type: Array, typeArguments: [String] }
    }
  },
  {
    kind: "interface",
    typeParameters: [_T],
    implements: [_Z],
    members: {
      method: {
        kind: "function",
        signatures: [
          { 
            typeParameters: [_U], 
            parameters: [_X, _T], 
            length: 2, 
            returns: _U 
          }
        ]
      }
    },
    index: [
      { 
        parameters: [String], 
        length: 1, 
        returns: { kind: "tuple", elements: [Number, Boolean] } 
      }
    ]
  }
)
...
var _X, _T, _U;

Metadata Example

interface Point {
  x: number; 
  y: number; 
}

interface Rect {
  p1: Point;
  p2: Point
}

class Frame {
  @dec
  outer: Rect;
  
  @dec
  inner: Rect;
}
var __decorate = ...;
var __metadata = ...;
var Frame = (function() {
  function Frame() {
  }
  // Point
  _a = { 
    kind: "interface",
    members: {
      x: Number,
      y: Number
    }
  };
  // Rect
  _b = {
    kind: "interface",
    members: {
      p1: _a, // Point
      p2: _a // Point
  };
  __decorate([
    dec,
    __metadata("design:type", _b) // Rect
  ], Frame.prototype, "outer");
  __decorate([
    dec,
    __metadata("design:type", _b) // Rect
  ], Frame.prototype, "inner");
  return Frame;
  var _a, _b;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment