Skip to content

Instantly share code, notes, and snippets.

@devsnek
Last active June 17, 2017 11:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devsnek/9752415df14102cbfd014ea5d4befbf5 to your computer and use it in GitHub Desktop.
Save devsnek/9752415df14102cbfd014ea5d4befbf5 to your computer and use it in GitHub Desktop.
requireTypeHintedFile.js
function test(asd: number, b: number) -> number {
return asd + b;
}
function test2(x: string, y: string) -> boolean {
return true;
}
module.exports = { test, test2 };
const fs = require('fs');
const Module = require('module');
const path = require('path');
const util = require('util');
const debuglog = util.debuglog('module');
const FN_REGEX = /function (.+?) ?\((.+?)\) ?-> ?(.+?) ?{((.|\n)+?})/g;
const ARG_REGEX = /([^, (]+?): ?([^) ,]+)/g;
function typingRequire(filename) {
let src = fs.readFileSync(filename).toString();
for (const fnMatch of src.match(FN_REGEX)) {
const ANNOTATION = {};
const ARGUMENTS = [];
FN_REGEX.tempIndex = FN_REGEX.lastIndex;
FN_REGEX.lastIndex = 0;
let [, name, args, returnType, body] = FN_REGEX.exec(fnMatch);
body = body.replace(/}$/, '');
FN_REGEX.lastIndex = FN_REGEX.tempIndex;
for (const argMatch of args.match(ARG_REGEX)) {
ARG_REGEX.tempIndex = ARG_REGEX.lastIndex;
ARG_REGEX.lastIndex = 0;
let [, argName, type] = ARG_REGEX.exec(argMatch);
ANNOTATION[argName] = type;
ARGUMENTS.push(argName);
ARG_REGEX.lastIndex = ARG_REGEX.tempIndex;
}
ANNOTATION.return = returnType;
src = src.replace(fnMatch,
`function ${name}(${Object.keys(ANNOTATION).filter(a => a !== 'return').join(',')}){${body}}
Object.defineProperties(${name},{
annotation:{value:${JSON.stringify(ANNOTATION)}},
args:{value:${JSON.stringify(ARGUMENTS)}},
})`);
}
const m = new Module(filename, module.parent);
debuglog('load %j for module %j (TYPE REWRITE)', filename, m.id);
m.filename = filename;
m.paths = Module._nodeModulePaths(path.dirname(filename));
m._compile(src, filename);
return m.exports;
}
module.exports = typingRequire;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment