Feature Request: Macros
See original GitHub issueThis one might be waaaaaay out of scope, but I think it is worth proposing. The idea here is to add support for macros, functions that run at compile time, taking one or more AST nodes and returning an AST node or array of AST nodes. Examples/use cases: (Syntax off the top of my head, open to better ideas)
Interface-Based Validation
// validation.macros.ts
function interfaceToValidatorCreator(interface: ts.InterfaceDeclaration): ts.Statement {
// Would return something like "const [interface.name]Validator = new Validator({...});",
// using types from the interface
}
macro CreateValidator(interface: ts.InterfaceDeclaration) {
return [interface, interfaceToValidator(interface)];
}
// mainFile.ts
/// <macros path='./valididation.macros.ts' />
@#CreateValidator // Syntax 1: Decorator-Style
interface Person {
name: string;
age: number;
}
PersonValidator.validate(foo)
Type Providers
// swagger.macros.ts
macro GetSwaggerClient(url: ts.StringLiteral): AssertionExpression {
// return something like "new SwaggerClient([url]) as SwaggerClientBase & {...}" where
// ... is an object creating the methods generated from the URL.
}
// mainFile.ts
/// <macros path='./swagger.macros.ts' />
var fooClient = #GetSwaggerClient("http://foo.com/swagger.json"); // Syntax 2: Function call syntax
fooClient.getPeople((people) => {
people.every((person) => console.log(person.firstName + "," + person.lastName);
});
Conditional Compilation
// conditional-compilation.macros.ts
macro IfFlagSet(flagName: ts.StringLiteral, code: ts.Statement[]): ts.Statement[] {
return process.env[flagName.string] ? code : []
}
// mainFile.ts
/// <macros path='./compilation.macros.ts' />
#IfFlagSet("DEVELOPMENT") { // Syntax 3: Language Construct-Like (multiple arguments can be passed in parentheses)
expensiveUnnecessarySanityCheck()
}
Notes
- Macros would run right after parsing. Not sure how we would deal with macros that need type information.
- This would make running
tsc
on unknown code as dangerous as running unknown code. It might be good to require a--unsafeAllowMacros
argument, not settable from atsconfig.json
. - It might be worth nothing in the docs that the AST format may change at any time, or something along those likes
- The
macro
keyword would probably compile to a function, followed by ats.registerMacro(function, argumentTypes, returnType
call. - Macros must be typed as returning a AST interface. This means that functions creating ASTs will probably need to have an explicit return type (or a calling function could have an explicit return type.
- Alternatively, we could consider giving the
kind
property special treatment inmacros.ts
files.
- Alternatively, we could consider giving the
- Just because a proposed syntax looks like a normal typescript construct doesn’t mean it behaves like one.
#Foo(interface Bar{})
is valid syntax, as long as there is a macro namedFoo
that takes an interface.- Exception: The Decorator syntax might need to be a bit more choosy (no decorating
1 + 1
, but decorating Interfaces, interface items, functions, etc. should be fine.
- Exception: The Decorator syntax might need to be a bit more choosy (no decorating
- This issue is likely to be updated quite a bit. For a log of changes, see the gist
Issue Analytics
- State:
- Created 8 years ago
- Reactions:622
- Comments:89 (18 by maintainers)
Top Results From Across the Web
Feature Request: Macros, Triggers, Automations in Explore
Feature Request Summary: I would like to be able to see data related to triggers, macros, and automations in Explore.
Read more >Feature Request: Add full text search in 'Execute a Macro'
Option 1: Include macro names in the results of an 'Add Action' search (Ctrl-Cmd+A). Yes, I know this shortcut is for actions, but...
Read more >[Feature Request] Support for linking items in macro by ID · Issue ...
I was curious if it would be possible to add the ability to link items via ID in QoL macros. Case usage, I've...
Read more >Aura title macro feature request - Atlassian Community
Solved: Hi! We use Aura plugin on the version 3.7.6, it's latest and greatest one for today. But I would to have a...
Read more >Feature request: UX improvements for Macros - Enonic Discuss
The macro dialog should automatically include a body HtmlArea where the content creator can add the body upon creation of the macro, and...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This would be huge. In something like Scala, macros are a way for the community to implement and test out new language features that are not yet (or will never be) supported by the core language.
After adding macro support, TS would have a large laboratory of potential features to draw on when implementing new ones, and could gauge support and feasibility of a feature before implementing it.
Features like pattern matching could first be implemented as macros, and then either moved into a standard macro lib, or into TS core if they are broadly useful and popular. This takes a burden off TS maintainers and authors, and gives the community freedom to experiment without forking the TS compiler.
This would truly be a killer feature for TypeScript and IMO might be a game-changer in the front-end language wars. As others have pointed out, macros would engage the community in evolving the language and providing highly expressive functionality to developers. In my case, I’d love to have a great pattern-matching syntax to go with TypeScript’s union types. (I am not impressed much by typeof and instanceof and long if-then chains.) I think a good macro system could provide this, and I imagine once TypeScript users had a reliable and appealing pattern-matching syntax, adoption would be swift. From a general language maintenance point of view, this would give language maintainers a standard way to implement many new features in the language without changing the source code of the language. The focus would shift to ensuring the macro system was bug-free, while keeping the core stable with few changes. This should improve the overall stability of the language while still providing most of the desired features people need.