feat: Runtime type reflection #17
@ -6,8 +6,8 @@
|
||||
scripts: {
|
||||
test: 'echo "Error: no test specified" && exit 1',
|
||||
build: 'tsc && cp etc/package.json build',
|
||||
exec: 'node build',
|
||||
go: 'pnpm --sequential "/build|exec/"',
|
||||
start: 'node build',
|
||||
go: 'pnpm --sequential "/build|start/"',
|
||||
},
|
||||
packageManager: 'pnpm',
|
||||
keywords: [
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type {Dependencies, Signature} from '../interfaces/type.js'
|
||||
import {$$typeToString, $$ts, $$define, $$raw, $$ident, $$escape} from 'ts-macros'
|
||||
import {$$typeToString, $$ident, $$escape, $$define} from 'ts-macros'
|
||||
import * as ts from 'typescript'
|
||||
|
||||
export const square =
|
||||
@ -50,21 +50,8 @@ console.log("Or maybe even", $$typeToString!<
|
||||
>())
|
||||
|
||||
// Now try to wrap it up in a macro
|
||||
|
||||
// From the creator of ts-macros; temporary until next release
|
||||
function $export(name: string, value: unknown) {
|
||||
$$raw!((ctx, name: ts.Expression, value: ts.Expression) => {
|
||||
if (!ctx.ts.isStringLiteral(name)) throw ctx.error(name, "Expected a string literal.");
|
||||
return [ctx.factory.createVariableStatement([ctx.factory.createToken(ctx.ts.SyntaxKind.ExportKeyword)], ctx.factory.createVariableDeclarationList([
|
||||
ctx.factory.createVariableDeclaration(name.text, undefined, undefined, value)
|
||||
], ctx.ts.NodeFlags.Const))];
|
||||
});
|
||||
}
|
||||
|
||||
// Obviously we'd prefer the name before the expression, but that won't work
|
||||
// until the next release
|
||||
function $exportImpl<Impl>(expr: Impl, name: string) {
|
||||
$export!(name, expr);
|
||||
function $exportImpl<Impl>(name: string, expr: Impl) {
|
||||
$$define!(name, expr, false, true); // Final `true` is export
|
||||
$$ident!(name).reflectedType = $$typeToString!<
|
||||
// <T>(...args: DeepExpand<Parameters<Impl<T>>>) => DeepExpand<ReturnType<Impl<T>>> // see comment in reflect below.
|
||||
Impl
|
||||
@ -73,9 +60,9 @@ function $exportImpl<Impl>(expr: Impl, name: string) {
|
||||
|
||||
// works but then not visible at import with current ts-macros.
|
||||
// Author says he will be enhancing this "soon."
|
||||
$exportImpl!(<T>(dep: Dependencies<'multiply', T>): Signature<'square', T> =>
|
||||
z => dep.multiply(z, z),
|
||||
'squire')
|
||||
$exportImpl!('squire',
|
||||
<T>(dep: Dependencies<'multiply', T>): Signature<'square', T> =>
|
||||
z => dep.multiply(z, z))
|
||||
|
||||
function $reflect<Impl>(expr: Impl) {
|
||||
return $$escape!(() => {
|
||||
|
@ -27,7 +27,7 @@ console.log('Type of square is', Specifications.generic.square.reflectedType)
|
||||
// Auto-generated export is invisible to TypeScript at the moment, author
|
||||
// says he will fix:
|
||||
console.log('Type of squire (auto-exported) is',
|
||||
// @ts-ignore
|
||||
// not ts-ignore
|
||||
Specifications.generic.squire.reflectedType)
|
||||
|
||||
// Via a macro wrapper around the definition, two ways:
|
||||
|
@ -4,8 +4,9 @@
|
||||
"rootDir": "./src",
|
||||
"outDir": "./build",
|
||||
"moduleResolution": "nodenext",
|
||||
"plugins": [
|
||||
{"transform": "ts-macros" }
|
||||
]
|
||||
"plugins": [ {
|
||||
"transform": "ts-macros/dist/type-resolve",
|
||||
"transformProgram": true
|
||||
} ]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user