0.3.1 • Published 5 years ago

stadt v0.3.1

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

CircleCI

stadt: a friendly representation of TypeScript types

This repository contains both

  • stadt, a definition of a series of interfaces that represent TypeScript types in a format that's amenable for static analysis (the ADT format)
  • stadt-converter, a library for converting a TypeScript type to ADT format.

This is split into two libraries because stadt-converter has a runtime dependency on TypeScript, but stadt itself doesn't.

Why does this exist?

To help make static analysis of JavaScript and TypeScript easier to write as part of the r2c analysis platform. Check out our site if that sounds like something you'd be interested in!

What's supported?

Currently supported:

  • String and numeric literal types
  • All primitive types (including unique symbol types**
  • Object literals
  • Union and intersection types
  • Types of classes and interfaces
  • Figuring out the package and file name that a type is defined in
  • Fallback 'untranslated' type serialization that just embeds the type signature as a string
  • Generics

Not supported:

  • The handling around recursive types (certain kinds of prototypes that have methods that return this) is still a little weird.
  • Boolean literals
  • Any actual logic for answering questions such as 'if I call this function with these arguments, what's the return type?'

Serialization format

stadt's data types use JSON as their serialization mechanism, and so can be consumed in your language of choice. See src/json.ts for documentation on what the data types look like, and see src/adt.ts for documentation on what the corresponding fields mean.

Demo

To try stadt out for yourself, clone it and run npm install, then run node ./dist/src/coverage.js /path/to/some/file. For example, running it on the source file for the 'coverage' binary itself gives:

Array.push @ 1290 : (...items: { ts: Type; position: number; text: string; adt: Type; }[]) => number ➡
    ObjectType {
      kind: 'object',
      properties: Map {},
      callSignatures:
       [ { parameters:
            [ { name: 'items',
                type:
                 NominativeType {
                   kind: 'nominative',
                   name: 'Array',
                   fullyQualifiedName:
                    { builtin: true,
                      fileName: undefined,
                      packageName: undefined,
                      name: 'Array' },
                   typeArguments: [ [ObjectType] ] } } ],
           returnType: PrimitiveType { kind: 'number' } } ] }

"util".inspect @ 2292 : typeof inspect ➡
    NominativeType {
      kind: 'nominative',
      name: 'inspect',
      fullyQualifiedName:
       { builtin: false,
         fileName: 'util.d.ts',
         packageName: '@types/node',
         name: 'inspect' },
      typeArguments: [] }

[...]

The output contains a serialized version of each AST node, its position, its type as stringified by TypeScript, and the output as a stadt object.

You can also use the stadt explorer, which lets you interactively type some JS and get an AST annotated with the types.

What's in a name?

"stadt" is an anagram of "TS ADT".