Skip to content

Instantly share code, notes, and snippets.

@walterra
Last active November 22, 2018 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save walterra/1dd998cf8d14e19f7dd90a98e4d4eb71 to your computer and use it in GitHub Desktop.
Save walterra/1dd998cf8d14e19f7dd90a98e4d4eb71 to your computer and use it in GitHub Desktop.
TypeScript Interfaces

TypeScript Interface

While working on annnotations, I thought about how TypeScript Interfaces could be valuable for validating js objects like an annotation itself.

TS's Interface can be thought of in analogy to PropTypes, but Interfaces can be applied everywhere, they don't work during run- but compile-time and are tightly integrated with VSCode's TS features.

So looking at the spec of the annotation format here, an Interface for an annotation can look like this:

export interface Annotation {
  _id?: string;
  timestamp: Date;
  end_timestamp: Date;
  annotation: string;
  job_id: string;
  result_type: 'annotation';
  detector_index?: number
}

This Interface defines kind of a contract about how each annotation object should be formed.

The Interface definition for an array of annotations looks like this:

export interface Annotations extends Array<Annotation> {}

Now, in VSCode, when you create an Annotation object, you get highlighting when you write some code which isn't applicable to the annotation's Interface, for example:

TypeScript Interface Linting Error

In the case above you cannot assign asdf because it accepts annotation only, something not doable with plain JS+Linting.

In the long run this can be quite valuable: If a modification is done the other way around, for example the format of annotations needs to change and therefor its Interface, then all the code using this Interface is automatically checked if it still applies to the contract of the Interface.

So the above is about IDE benefits and finding problems at compile time.

For runtime checks we can create a custom function which references the Interface and does some duck typing on top:

export function isAnnotation(arg: any): arg is Annotation {
  return (
    arg.timestamp !== undefined &&
    arg.annotation !== undefined &&
    arg.job_id !== undefined &&
    arg.result_type === 'annotation'
  );
}

The return check is simple duck typing and can be customized, it's independent of TypeScript itself and is meant for runtime. On top of that you get the benefit of TypeScript's VSCode integration and checks on compile time with how the function's definition is written. This function can also be imported and used from non-TypeScript code. So this is valuable for checking objects created on runtime, for example when creating a new annotation or when retrieving annotations from the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment