4 ms·
In theory, typescript doesn't need to be transpiled, you can run ts files using `node --experimental-strip-types file.ts` as long as you don't use any code that
by Cthulhu_ 4mo ago
In theory, typescript doesn't need to be transpiled, you can run ts files using `node --experimental-strip-types file.ts` as long as you don't use any code that needs transpilation (like typescript enums).
Still need tsx to do type checking
- ivanjermakov 4mo agoNo, because of ESM import resolution rules. Typescript suggests extensionless imports, making it incompartible with ESM and therefore Node. Luckly, `node --import=tsx file.ts` handles imports well. This is especially hairy when making a typescript library that is distributed non-compiled (without dist/) and is supposed to run in both browser and Node. https://github.com/nodejs/node/issues/46006 https://github.com/nodejs/node/issues/46006 https://github.com/microsoft/TypeScript/issues/16577 https://github.com/microsoft/TypeScript/issues/16577
- MrJohz 4mo agoYou can use one of the following: `allowImportingTsExtensions: true` (https://www.typescriptlang.org/tsconfig/#allowImportingTsExtensions https://www.typescriptlang.org/tsconfig/#allowImportingTsExt..., useful if you're running `tsc` in noEmit mode as a linter) `rewriteRelativeImportExtensions: true` (https://www.typescriptlang.org/tsconfig/#rewriteRelativeImportExtensions https://www.typescriptlang.org/tsconfig/#rewriteRelativeImpo..., useful if you're using `tsc` to compile TS files to JS. This allows you to use fully-specified imports in TypeScript files, which works basically everywhere — NodeJS, TypeScript, bundlers, etc. The exceptions are browsers (obviously, only normal JS syntax there), and packages inside `node_modules`, which NodeJS will not do any type stripping for. So if you're writing a library, you'll probably still need to distribute the compiled sources, rather than distributing the raw TypeScript files alone. Or you use the JSDoc syntax for TypeScript, which can do everything that .ts files can do, but is more verbose and idiosyncratic.
- moogly 4mo agoI transpile for prod, but use --strip-types when running in dev, and all I had to do was to make a 10-line ESM register hook that rewrites .js to .ts if the .js import fails, and then a one-liner import register trampoline script. Not sure I'd do that in prod, but works fine in dev at least. This way I could just use node --watch instead of tsx or nodemon.
- ivanjermakov 4mo agoMind sharing the implementation? I think it's basically what tsx is doing when used in `node --import tsx`.
- moogly 4mo agoSure. No need for --(experimental)-strip-types since I-forget-which-version, but I use Node.js 24.17 here. // ---- dev-ts-resolve.js export async function resolve(specifier, context, nextResolve) { try { return await nextResolve(specifier, context); } catch (err) { const isRelative = specifier.startsWith('./') || specifier.startsWith('../') || specifier.startsWith('/') || specifier.startsWith('file:'); if (err?.code === 'ERR_MODULE_NOT_FOUND' && isRelative && specifier.endsWith('.js')) { return nextResolve(`${specifier.slice(0, -3)}.ts`, context); } throw err; } } // ---- dev-loader.js import { register } from 'node:module'; register('./dev-ts-resolve.js', import.meta.url); // ---- usage: node --import ./dev-loader.js --watch-path=./src