Code Monkey home page Code Monkey logo

ts-visitors's Introduction

ts-visitors

An exploration of typed visitors in TypeScript

Getting started

$ git clone [THIS-REPO]
$ cd ts-visitors
$ npm i

Type narrowing

ASTs have nodes of multiple kinds. TypeScript defines the nodes of its AST to extend from a single common interface (Node). It exposes a single visitor ts.forEachChild(node: Node, cbNode: (node: Node) => T | undefined, ...) that gets executed for all nodes. No kind specific callbacks are provided so that any kind specific logic has to be placed within the same visitor.

We explored the benefits of defining a visitor that provides kind specific callbacks and leverages type narrowing through unions: ts-ast-utils.

We compared 3 different approaches solving the same problem: printing the constructor and method signatures of a class in a declaration file. For this we manually created a declaration file for the Pair class defined in Featherweight Java. Finally, we defined an AST for it. The same AST was used for all approaches. Each approach however defines its own typings for the same AST.

  1. acceptWithTypeScriptVisitor: Inspired by the TypeScript's visitor. No kind specific callbacks are provided. No type narrowing, a single common interface is used when a type represents different node kinds, e.g. the members of a class.
  2. acceptWithInheritance: Kind specific callbacks. No type narrowing, a single common interface is used when a type represents different node kinds, e.g. the members of a class.
  3. acceptWithUnion: Kind specific callbacks. Type narrowing through unions is used for the cases when a type represents different node kinds, e.g. the members of a class.

acceptWithTypeScriptVisitor

(Link)

Run example:

$ npm run script -- src/type-narrowing/1_acceptWithTypeScriptVisitor/examples/printClasses.ts
  • The same callback is used for all nodes. The kind specific logic needs to be placed inside the common callback. In our case, we are interested in the ClassDeclaration. The type guard isClassDeclaration() is used for this.
  • User needs to go through documentation to investigate which type guards are available.
  • Type guards need to be used also to handle the class members.

acceptWithInheritance

(Link)

Run example:

$ npm run script -- src/type-narrowing/2_acceptWithInheritance/examples/printClasses.ts
  • Kind specific logic is placed in the specific callback for ClassDeclaration. The type guard isClassDeclaration() is no longer needed.
  • Kind specific callback matching is hidden behind a node as any clause: see here.
  • The type ASTNodeKindsTable is introduced to enable the kind specific callback.
  • User can easily use the IDE and code intelligence tools to inspect all available kind specific callbacks.
  • No type narrowing is used. Type guards need to be used also to handle the class members. The type ASTClassElement is a common single interface. The user needs to go through the documentation to identify which nodes are class members.

acceptWithUnion

(Link)

Run example:

$ npm run script -- src/type-narrowing/3_acceptWithUnion/examples/printClasses.ts
  • Kind specific logic is placed in the specific callback for ClassDeclaration.
  • ASTNode is defined as the union of all possible nodes instead of defining it as a single common interface.
  • The type ASTClassElement is explicitly defined as the union of the possible members.
  • No type guards are needed. The compiler narrows the types automatically.
  • User can easily use the IDE and code intelligence tools to also inspect all available class members.

ts-visitors's People

Contributors

f-cristiani avatar proglang avatar

Stargazers

Tim Kersey avatar

Watchers

James Cloos avatar Peter Thiemann avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.