Typescript: custom syntax providers

Created on 10 Feb 2018  路  7Comments  路  Source: microsoft/TypeScript

it would be great to be able to use pluggable non-typescript syntax right in the typescript code

for example, i need a notion of a valid URI literal, i have its grammar ready, i wish there was a way to specify a valid URI in a typescript code and get it checked at the compile time

currently my options are:

  1. constructor functions (fail only at runtime)

     const uri = parseUri('http://google.com');
    
  2. builders (unnatural, clumsy)

     const uri = new UriBuilder().protocol('http').host('google.com').done();
    

i wish i could do something like this:

const uri: URI via URIParserAndEmitter = http://google.com; // <-- terse & natural, fails at build
// or 
const uri: via URIParserAndEmitter = http://google.com; // <-- terse & natural, fails at build

how it works

in the last example URIParserAndEmitter refers to a plugin that:

  1. takes over and parses the expression on the right side of = at compile time
  2. fails if needed
  3. passes the parsed AST to the custom TS emitter (part of the plugin)
  4. spits out the resulting piece of TS AST back to the TS compiler

parsing scope

TS should not care or limit how far the custom parser can go in the source text of the file:

  • if parsing is successful, take the control back from the next unconsumed character, assuming getting back to the statement, expression, or declaration context depending on where the custom parsing started
  • if parsing fails, do not attempt to parse the rest of the file (price to pay for simplicity of things)

applications

  • units of measure
  • integer numbers (no frations), positive numbers (no negative sign)
  • emails, markdown
  • jsx, xml, html
  • any DSL (domain specific language)
  • c#, c++, java, ....

pros

  • one time investment that gives unlimited extensibility
  • anyone can take part in extending the language

cons

  • anyone can take part in extending the language
  • the repository of approved extensions of high quality needs to be managed (akin @types)
  • parsers might collide
Out of Scope

Most helpful comment

The folks who run Svelte are betting on compilers being the next step in frameworks. If that bet pans out, then a feature like this would allow projects to properly type things in their system, which would let downstream devs reap the benefits of TS, even with strange framework-specific syntax. React works beautifully in TS. It'd be cool if that kind of deep integration was available to others.

All 7 comments

I think this may be took so far on changing the syntax
If we can limit this to a string template that might be better

Like this
import
URIParserAndEmitter from ....
const u = URIParserAndEmitter(url)

This URIParserAndEmitter both generate runtime code (like a normal library) and claim itself as a typescript plugin (get type info from typescript, provide type checking), and can safely downgrade to that not support plugin one

any expression in any language is self-contained

  • string literal goes up to "
  • number literal goes up to last digit
  • JSON literal goes up to the last (balanced) closing brace

it doesn't seem that the scope of an expression needs to be limited

I wish that was simple to add. the reality is everything in the compiler relies on the AST kinds, and having new kinds added to the system affects everything. Maybe if we had a system that abstracts about all of these details and can reason about code constructs in a high-level fashion it would be easier.

you add a special AST node with kind of SyntaxKind.Plugin = 255 which would be an escape hatch from TS to whatever plugins use, then next to the kind you add a subkind of a string which would hold a sort of guid or a namespace that would be a marker for plugins to it's their stuff

think about // comments you don't do much with them (well maybe now you do) but the idea is the same

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

The folks who run Svelte are betting on compilers being the next step in frameworks. If that bet pans out, then a feature like this would allow projects to properly type things in their system, which would let downstream devs reap the benefits of TS, even with strange framework-specific syntax. React works beautifully in TS. It'd be cool if that kind of deep integration was available to others.

Was this page helpful?
0 / 5 - 0 ratings