How to make a shell executable node file using TypeScript

bash, command-line-interface, node.js, typescript

Solution

You were right to report the bug to Microsoft, and they were wrong to close it as wontfix.

Until it is fixed, here's a workaround. Paste the following into a text file and save it as `shebangify`:

#!/usr/bin/env node
var fs = require('fs');
var path = process.argv[2];
var data = "#!/usr/bin/env node\n\n";
data += fs.readFileSync(path);
fs.writeFileSync(path, data);

(N.B. To keep this answer concise, the code above doesn't have any error-checking or other refinements, so use at your own risk or use this instead. Also, see this SO question for more info about prepending to files.)

Make the file executable with by using a terminal to navigate to the file's directory and executing:

$ chmod +x shebangify

Once you have created a Typescript program (e.g. called `myscript.ts`) that you wish to compile and turn into a shell script (e.g. called `myscript`), do so by executing a sequence along these lines in your terminal:

$ tsc --out myscript myscript.ts ; ./shebangify myscript ; chmod +x myscript

Problem

Normally in node files I just put ``` #!/usr/bin/env node ``` at the top and make it executable to create a file that can be run from a bash terminal. However if I do that in a Typescript file, the compiler says "error TS1001: Unexpected character "#"" and refuses to compile it. So how can I make a shell executable node file with Typescript? Update: This has been fixed https://github.com/Microsoft/TypeScript/issues/2749 shebangs now passthrough

Original source