Releases: GoogleFeud/ts-macros
Releases · GoogleFeud/ts-macros
v2.2.1
v2.2.0
Additions
- Expanded the functionality of type parameters of macros. You can now pass complex types which include type parameters to built-in macros which expect type parameters like
$$typeToString
,$$propsOfType
and$$typeAssignableTo
. - A
.
repetition separator which creates a property / element access chain out of the expressions. - A
{}
repetition separator which creates an object literal out of the expressions. For this separator to work, the result of the repetition callback must be an array literal with 2 elements - the key and the value ([key, value]
). - Added the
SyntaxKind
enum to the playground so now you can use$$kind
properly.
This version of ts-macros adds a bunch of useful built-in macros which give you the ability to transform expressions without ever touching the typescript AST API. Click on the macro names to learn more about them and see examples.
- A
$$text
built-in macro that tries to stringify an expression. - A
$$decompose
macro that decomposes an expression by expanding to an array literal with the nodes that make up the expression. For example, for the expressionconsole.log(1)
, the macro call would expand to[console.log, 1]
. - A
$$map
macro that takes a function that acts as a macro and goes over all the nodes of an expression with it, replacing each node with the expanded value of the macro function. It is a recursiveArray#map
but for expressions. - A
$$typeAssignableTo
macro which compares two types.
Changes
- If there's nothing to repeat, a repetition will now expand to
null
instead of throwing an error. - Repetitions now expand blocks properly if used as an expression.
- Macro imports now get removed from the transpiled code (#48).
- Empty namespaces get removed from the transpiled code, which means you can freely store macros in namespaces!
Bug fixes
- Fixed bug with nested repetitions possibly causing a stack overflow.
- Fixes #47
v2.1.0
Additions
- An
error
method in theRawContext
object so you can create lovely error messages. (#32) $$typeToString
now accepts a second parameternonNull
, which removesnull
andundefined
from types, sostring | undefined
becomesstring
.- An
$$inline
built-in macro that has more functionalities than the current$$inlineFunc
macro. - Macro variables: You can create macro variables which get removed from the final code. Macro variables must start with
$
like a regular macro does.function $test<T>(value: T) { const $type = $$typeToString!<T>(); if ($type === "string") return "Value is a string."; else if ($type === "number") return "Value is a number."; else if ($type === "symbol") return "Value is a symbol."; else if ($type === "undefined" || $type === "null") return "Value is undefined / null."; else return "Value is an object."; } const a = $test!(null); const c = $test!(123); const f = $test!({value: 123}); // Transpiles to: const a = "Value is undefined / null."; const c = "Value is a number."; const f = "Value is an object.";
- You can now use the
+
unary operator on string literals to turn them into numeric literals during compile time.
Changes
- Made errors coming from comptime functions (
$$comptime
and$$raw
) prettier. - Previously the
$$escape
function would expand tonull
if the function's body is not a block, this is no longer the case:const num = $$escape!(() => 1); // Before: 1; const num = null; // Now: const num = 1;
- You can now pass any function to
$$escape
,$$inline
,$$comptime
, and$$raw
- function declarations, references to function declarations, arrow functions, and anything callable with a body.const add = (a: number, b: number) => { return a + b; } console.log($$inline!(add, [1, 2])); // Transforms to: function add(a, b) { return a + b; } console.log(1 + 2);
null
is considered a literal now.- The
$$inlineFunc
macro is now deprecated and will be removed in the next major version. - The
$$getStore
and$$setStore
macros are now deprecated and will be removed in the next major version.
Bug fixes
- Fixes #35.
- Fixed bug where if you pass nothing to an optional parameter, the optional parameter expands to an invalid expression instead of
undefined
(#38). - Fixed bug in
$$raw
where skipped optional parameters wereundefined
instead of the undefined node. - Fixed bug with the
typeof
operator that made It so macro parameters wouldn't expand to anything. - Fixed #40.
- Fixed a bug with deconstructing assignments in macros not being hygienic.
v2.0.1
Bug fixes
- Fixes bug where using built-in object methods (for example
toString
) would break the transformer. - Fixes bug where template literals break when the macro's used in another file.
- Support for typescript 4.9.x.
- Fixes #29
Changes
- Adds a
simplify
argument to the$$typeToString
built-in macro which turns literal types like"string"
toString
,123
toNumber
,true
toBoolean
, etc.
v2.0.0
Breaking changes
- Spread parameters no longer get automatically included in repetitions. Now that a repetition expression can accept an array of array literals, this isn't necessary and it only adds confusion.
- With the removal of spread parameters from repetitions, you can no longer have a repetition that goes over multiple variables. To allow this behavior, the repetition callback parameters can now be used to separate elements:
Visit the docs to learn more!
function $test() { console.log(+[[[1, 2, 3], ["a", "b", "c"], [7, 8, 9]], (first: number, second: string, third: number) => first + second + third]); } $test!(); // console.log("1a7", "2b8", "3c9");
- The
$$escape
macro can now be used as an expression. If the last expression in the arrow function is a return statement, the escape macro will expand to the returned expression. - Removed the
Var
marker.
Additions
$$raw
macro that allows you to use the typescript and ts-macros APIs directly inside macros.- Decorator macros - the macro receives the declaration the decorator is for and using the
$$raw
macro it can modify it and return a new declaration:function $editClassName(newName: string) : EmptyDecorator { return $$raw!<EmptyDecorator>((ctx, newNameNode: ts.StringLiteral) => { const target = ctx.thisMacro.target as ts.ClassDeclaration; return ctx.factory.updateClassDeclaration( target, undefined, ctx.factory.createIdentifier(newNameNode.text), target.typeParameters, target.heritageClauses, target.members ) }); } @$editClassName!("NewA") class A {} // Compiles to: class NewA {}
$$getStore
and$$setStore
macros which replace theVar
marker.- Spread elements in array literals now get expanded if the element is an array literal.
noComptime
macro option which disables all macros which run arbitrary code during compile-time ($$raw
and$$comptime
). When this option is set totrue
, they expand tonull
.
Bug fixes
- Fixes #22
- Fixes #25
- Fix bug with rest operator - if literals aren't passed in place of the rest parameter, a new array gets created (
[...items]
). This is no longer the case. - Fixed bug with escaping statements. (
$$escape
andSave
)
Thanks
v1.3.6
v1.3.5
v1.3.4
v1.3.3
Additions
- A
$$comptime
macro that's heavily inspired by Zig'scomptime
keyword. It gives you the ability to run typescript code during
transpilation. A simple example:
$$comptime!(() => {
// This will be logged when you're transpiling the code
console.log("Hello World!");
});
And just like Zig's comptime, if it's used in a function, you can access the function's parameters as long as they are literal values:
const greet = (name: string) => {
$$comptime!(() => {
console.log(`Hello ${name}`);
});
}
greet("Michael"); // Logs "Hello Michael" during transpilation
let name: string = "Bella";
greet(name); // Logs "Hello undefined"
v1.3.2
Bug fixes
- Fixes #8
Changes
-
All built-in macros which accept a string can now accept template literals:
function $test(str: string) { return $$length!(`Hello ${str}!`); } $test!("Google"); // Transpiles to: 13;
-
$$length
can now accept a string. -
When a type parameter is provided in
$$typeToString
and$$propsOfType
, it can be inferred:function $doSmth<T>(thing: T) { if ($$typeToString!<T>() === "string") console.log(1); else if ($$typeToString!<T>() === "number") console.log(2); else console.log(3); } $doSmth!(123); $doSmth!("ABC"); $doSmth!(true); //Transpiles to: "number"; "string"; "boolean";