2

So basically I would like to use TypeScript to check my code for errors while in editor (VS Code), but don't want to do any transpilation steps.

I have my code in .js files, and "allowJs": true in tsconfig.json

The only problem is, the editor would complain about usage of typescript-words inside js files, for example:

declare module "something" {
    export interface MyInterface {

Leads to error:

 "'module' declarations can only be used in TypeScript files"

I tried not to give a damn but unfortunately, it also leads to error while running the actual (node.js) program!

SyntaxError: Unexpected strict mode reserved word
    at Loader.moduleStrategy (internal/modules/esm/translators.js:145:18)

Can't I somehow have TS checks without TS?

I know I can, I mean it's right there but then I have to delete everything related to TS before app launching.

IDK maybe someone has a... transpiler for that? :D

Surprisingly there's not much information about this on the Internet.

The reasons why I won't transpile TS to JS:

  • It spends time
  • The code is a mess. It has random functions I never wrote, also "var" everywhere
  • Errors have line numbers from .JS files which are autogenerated (f**ked up)
  • Why would I compile a scripting language anyway
E_net4
  • 27,810
  • 13
  • 101
  • 139
Ni Xt
  • 35
  • 8
  • You simply need to add a separate `.d.ts` file and declare your types there. see: [How to use TypeScript declaration files alongside JavaScript](https://stackoverflow.com/questions/61932377/how-to-use-typescript-declaration-files-alongside-javascript) or [About "*.d.ts" in TypeScript](https://stackoverflow.com/questions/21247278/about-d-ts-in-typescript) – pilchard Nov 08 '21 at 21:52
  • Your experience is not going to be very nice if you don't add type annotations (=requires transpiler) but it might be better than nothing – erikkallen Nov 08 '21 at 21:58
  • Thanks .d.ts file actually helped. Seems like I don't even have to include it in a project. But yes, I would love to have annotations in functions, etc. – Ni Xt Nov 08 '21 at 22:15
  • UPD: I realised that my .js files were changed so much because I used SWC instead of TSC. TSC seems to only delete spaces from files. Hm. Gots to find a way around that. – Ni Xt Nov 09 '21 at 00:29

1 Answers1

1

Yeah, you absolutely can. And you don't need TypeScript declaration files either.

TypeScript will happily check your vanilla JS code if you have the checkJs flag set in either CLI config or your tsconfig.json file. allowJs actually has nothing to do with it, that just enforces whether you can import vanilla JS files into TS/TSX files (it doesn't care if you import JS into JS). JSDoc annotation is actually a great way to mix vanilla JS and TS code in a mixed codebase, for example if you're in the process of migrating code from JS to TS.

TypeScript (even without JSDoc annotations) will give you tons of useful "implicit" type checking without writing any extra syntax, just by detecting how you declare variables and assuming that their type shouldn't change (among other inferences):


// Implicit TypeScript typing
let myBooleanValue = false;
myBooleanValue = 'true'; // Error: Type 'string' is not assignable to type 'boolean'.ts(2322)

If you want even more control however, TypeScript is fully compatible with JSDoc type annotations. Make sure you read the documentation and use the proper comment syntax (e.g. /** ... */ not // ...). There's just about nothing you can do with TypeScript syntax that you can't do with JSDoc, it's just a bit wordier:

// Explicit JSDoc typing
/**
 * @type {string}
 */
let myVar;
myVar = 7; // Error: Type 'number' is not assignable to type 'string'.ts(2322)

You can get even more advanced with it, declaring things like function parameters, object structure and nested fields, return values, and more:

/**
 * @param {object} myParam
 * @param {number} myParam.myNumber
 * @returns {boolean} // Error: A function whose declared type is neither 'void' nor 'any' must return a value.ts(2355) (because nothing is currently returned from myFunction)
 */
function myFunction(myParam) {
  let myNumberCopy = myParam.myNumber;
  let myMissingPropertyCopy = myParam.myMissingProperty; // Error: Property 'myMissingProperty' does not exist on type '{ myNumber: number; }'.ts(2339)
}

You can even do crazy stuff like import types from other files or packages and use it in your JSDoc annotations:

/**
 * @type {import("React").FC}
 */
const MyComponent = () => null;

Here is the tsconfig.json file I used for the above examples, with nothing except basic typescript NPM package installed:

{
  "compilerOptions": {
    "module": "es6",
    "noEmit": true,
    "checkJs": true,
    "moduleResolution": "node"
  },
  "include": ["src/**/*"]
}

Visual proof that this all works great in VSCode: screenshot of VSCode

With this setup a good way to "test" whether you have any type errors in your entire codebase is to run npx tsc --noEmit, which will run TypeScript checking (including the JSDoc annotations) for all your files, according to your tsconfig.json file.

E_net4
  • 27,810
  • 13
  • 101
  • 139
jered
  • 11,220
  • 2
  • 23
  • 34
  • Thanks! I had JSDoc comments in my code before. Though I think typescript annotations are better. Basically my problem is that I can't figure out where the error is with wrong lines in files. If it's possible for typescript not to change anything besides removing the annotations, it's fine. – Ni Xt Nov 10 '21 at 16:37
  • What do you mean by "I can't figure out where the error is with wrong lines in files"? – jered Nov 10 '21 at 19:55
  • Nodejs writes errors to console, say "something happened on line N", but since my TS files differ from actual JS ones, line numbers are completely wrong (N+1, N+123, etc). And all this stuff runs in a specific environment, I have less control over it than over regular nodejs app (no debugging possible). – Ni Xt Nov 10 '21 at 23:25