-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage question: Changing type checking of operators #15
Comments
hey mate! no you're exactly right - it will only type check as if it were we can however write type def transformers if you want to change what typedefs are generated |
Hey! Thank you so much for your reply – and for the handbook! I'd be lost without it. These are some unfortunate news. In order for my “modified TypeScript” to be useful at all, I need custom type-checking… This means that transformers can't do the job for me and I'll have to use the Compiler API directly and make TypeScript generate types when I want to, right? I'll try messing with the compiler and if I manage to do something interesting, I'll let you know 😁️ |
yeah you basically need to use it directly.. no idea how it will go! if you find anything interesting report back :D |
With the help of the StackOverflow community (see my question) I was able to get the compilation working. I had to write a few utility functions that are available in a gist, with them the code looks like this: import * as ts from "typescript"
import { rewriteNode, rewriteChildren } from "./rewrite";
function compile(fileNames: string[], options: ts.CompilerOptions): void
{
let program = ts.createProgram(fileNames, options)
for (let input of program.getSourceFiles())
if (input.fileName.endsWith('.m.ts'))
rewriteNode(input, visitor)
logDiagnostics(ts.getPreEmitDiagnostics(program))
let emitResult = program.emit()
logDiagnostics(emitResult.diagnostics)
let exitCode = emitResult.emitSkipped ? 1 : 0;
console.log(`Process exiting with code '${exitCode}'.`)
process.exit(exitCode)
}
const operatorNameMap: { [op in ts.SyntaxKind]?: string } = {
[ts.SyntaxKind.PlusToken]: 'op_plus',
[ts.SyntaxKind.MinusToken]: 'op_minus',
[ts.SyntaxKind.AsteriskToken]: 'op_asterisk',
[ts.SyntaxKind.SlashToken]: 'op_slash'
}
function visitor(node: ts.Node): ts.Node {
if (node.kind === ts.SyntaxKind.BinaryExpression) {
let expr = node as ts.BinaryExpression;
const name = operatorNameMap[expr.operatorToken.kind]
if (name !== undefined) {
const identifier = ts.createIdentifier(name);
return ts.createCall(identifier, undefined, [expr.left, expr.right]);
}
}
return rewriteChildren(node, visitor);
}
function logDiagnostics(arr: readonly ts.Diagnostic[]) { /* long uninteresting code */ }
compile(['sample.m.ts'], {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.CommonJS
}) Now I need to hook it up to the language services… |
I'm frequently working with symbolic mathematical expressions. Sadly, JavaScript doesn't support operator overloading, so I have to write a lot of ugly code like
add(u, mul(2, v))
. I would love to make a transformer that changes operators into function calls:This transformation alone is quite easy, I just have to find
BinaryExpression(A, op, B)
and turn it intoCallExpression(fn, [A, B])
. However I would love to use the type checking of the resulting function. In the handbook you say that:Does this mean that my transformed code will still be type-checked as if it were
a + b
, notop_add(a, b)
? Or is it just a misunderstanding on my side?Thanks!
The text was updated successfully, but these errors were encountered: