You Might Not Need

TypeScript

(a pure JS alternative)

Darren DeRidder

@73rhodes

Thoughts on Types

Why use types then?

  • Useful for static analysis: hinting, linting, code completion.
  • Ideally, up front in dev tool chain; IDE plugins etc.

Tools for Types

  • JSDoc
  • Flow
  • TypeScript

Type Definitions with JSDoc

  • Doesn't invalidate your JavaScript.
  • No transpiler needed.
  • Annotations are kept in comments.
  • Code and typedefs together: no separate typings module eg. `@types/foo`.
  • Useful on its own as documentation.

Getting Started

✅ javascript.implicitProjectConfig.checkJs
jsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    "checkJs":  true,
    "target": "es2015"
  },
  "exclude": [
    "node_modules/"
  ]
}
                    

Defining types


/**
 * @typedef CoverageTotals
 * @property {number} totalCoverItemScores
 * @property {number} totalCoverItemWeights
 */
                    

Declaring a type


    /** @type {coverageTotals} rc */ 
    let rc = {
      totalCoverItemScores: 0,
      totalCoverItemWeights: 0
    };
                    

Type Casting


                   let auth = /** @type {typedefs.Person} */(book.author);
                   
Note the parenthesis around expression being typecast.

Inheritance / Extending


/**
 * @typdef FooAttributes
 * @property {string} foo
 * @property {number} fizz
 *
 * @typedef BarAttributes
 * @property {string} bar
 * @property {number} buzz
 *
 * @typdef {FooAtributes & BarAttributes} Foobar
 */
                    

Types in separate file

Empty module eg. typedefs.js:

                    /**
                     * @file typdefs.js
                     *
                     * ... JSDoc typedefs
                     */
                    module.exports = {}
                    
Using it:

                    const typedefs = require("./typedefs");
                    

Typdefs for Node


                    npm install @types/node
                    
Typescript / JSDoc typdefs can co-exist :-)

Typedef as one of several strings


                    /**
                     * @typedef {('assert' | 'cover' | 'assume')} AssertionKind
                     */
                    

Module Exports

Be careful declaring module exports. Intellisense has trouble recognizing some module export syntax.


                    // Borken.
                    module.exports = {
                       myMethodA,
                       myMethodB
                    };
                    

                    // Not borken.
                    exports.myMethodA = myMethodA;
                    exports.myMethodB = myMethodB;
                    

Interoperability

@type can refer to a TypeScript OR a JSDoc type definition.

What about other IDEs?

Configuring Sublime for Modern ES Projects