DEV Community

Adam Crockett 🌀
Adam Crockett 🌀

Posted on • Updated on

Make Typescript less typesafe

I am using Typescript to give VSCode some idea of what my Rhino JavaScript (Java JavaScript) is doing, I am not using Typescript sources, I am still using JavaScript files with checkJS turned on.

(I know it sounds terrible but I know the risk, all safety off)

I have several scripts executed in a sandbox with injected variables that includes the entire Java OpenJDK, I dont want to provide typedefs for this, but I do want to provide some hints, what can I do to make TS not care about 1000's of globally injected variables and objects.

Short of building Typedefs from Java (Done this it too 5 hours to build, its not going to work)

I want to do this:

java.io.readFile(); // < TS wont care about this

context.outcome; // hey TS there is this thing I have defined, its a boolean

(2).map(); // TS this isn't right!
Enter fullscreen mode Exit fullscreen mode

Top comments (24)

Collapse
 
ssimontis profile image
Scott Simontis

I feel you hard on this. I come from a C# background in which everything is type-checked to an extent that you become far more comfortable with generics than you thought possible. At my current position, we exclusively use TypeScript. Some of our codebase is still ES6 and some JS libraries really just feel super awkward in TS.

I've learned to embrace it a little bit, I still try to minimize my use of declaring stuff any, but sometimes that or creating incredibly specific interfaces are the only way I know to make my code compile.

However, I've also been embracing discriminated unions as a solution to a lot of my issues. It isn't applicable to every situation, but I feel like it's a big level-up for my expressibility

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Ah C# I plan to try this out one day, but as a close relative of TS In terms of parentage, I can see the appeal.

Most of the time TS works fine but there's always a... "Hang on I don't need to protect this bit, it's already safe" or you may need an any.

In the early days I used Typescript for everything but now I use of for stuff that will be maintained, preferring prototype work in JavaScript.

Anyway for this task I have turned on type checking in js and not wrote a single TS file, only including a tsconfig file, not standard stuff, the JavaScript is executed in a sandbox ran from the Java side and we are injecting variables into that context, the entire Java stdlib is just too much to write out by hand but I do want some of the good bits...

It's too complex I fear, I may try flowtype instead, see how that works

Collapse
 
ssimontis profile image
Scott Simontis

I feel like your best bet to "do it the rightish way" would be creating some sort of code generator which could either parse the Java stdlib, pull method signatures from library files, or maybe even read code-completion data from another IDE like Eclipse. But I can see that getting out of hand and becoming a thesis project really quickly, haha.

I have used Flow before, and there is definitely a lot less support in terms for editor/IDE extensions, and I had the impression that the project had lost a lot of steam.

Thanks for posting this adventure though, I always love reading the insightful questions you post!

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

Oh man the result of this was a 5 hour build job, even declaring all the globals as any from the Java stdlib was really slow for the language server and vscode to handle. Unserpising.. I think I will give up on this for now

Collapse
 
neociber94 profile image
Neo-Ciber94

Did you play with the compiler options: noEmit: true, incremental: true?

I never knew I will want TypeScript so much, until I need to maintain an undocumented 2 years old code where they use "any" anywhere

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

So we are not emitting because we are using JavaScript sources and the backend is just checking JS. Anyway this answer seems to lead to a different question that I'm not asking but thank you anyway

Collapse
 
stefnotch profile image
stefnotch

For global variables, I don't think there is an option other than providing Typescript definitions for every single global variable. As in, take the list of injected variables. Then, create a java.d.ts with something along the lines of

declare const java: any;
declare const System: any;
declare const StringBuilder: any;
...
Enter fullscreen mode Exit fullscreen mode

Something like modifying the global object doesn't quite cut it

declare global {
  interface Window {
    [key: string]: any;
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
adam_cyclones profile image
Adam Crockett 🌀 • Edited

For global variables, I don't think there is an option other than providing Typescript definitions for every single global variable

sigh it's as I feared, I have kind of done both but taken to the absolute extreme, generating all of the definitions from jars... But it was too much for
A: My CPU, B: the language server.

It took 5 hours to compile using multithread techniques in node, 33000 classes. It turned into a funny novelty challenge, (I was quite happy to have created a reliable compiler actually, probably the most resilient thing I have ever made). So yeah, a good plan if the language server was damn fast, but it's not so that's scrapped. Maybe I could try flowtype if that's sstilla thing. Or I could give up 😅

Collapse
 
aheisleycook profile image
privatecloudev

why not use lilscript

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Cool, but it's not quite what I'm looking for, I'm staying with a well known solution (because our new devolpers are more likely to know typescript)

Collapse
 
aheisleycook profile image
privatecloudev

True still a good option

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

What's that, can't see any Google results

Collapse
 
aheisleycook profile image
privatecloudev
Collapse
 
aheisleycook profile image
privatecloudev
Collapse
 
tarekali profile image
Tarek Ali

If you don’t want type safety, just use JavaScript?

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

All explained in the description

Collapse
 
wagyourtail profile image
wagyourtail

I have a javadoc doclet for creating typedefs from java in my graaljs project... you'll probably have to use declare and/or cast to any

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

That sounds most realistic 👍

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
adam_cyclones profile image
Adam Crockett 🌀 • Edited

Ummm Typescript can be functional, it's just JavaScript, most people do use it functionally... But that's nothing to do with type safety, there are plenty of typesafe functional languages, F# for example

Collapse
 
srachamim profile image
SRachamim

Take a look at the fp-ts ecosystem. That's real functional programming, and that's one easy way you can write more type-safe code.

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀

But I'd didn't ask for functional code 🥴

Thread Thread
 
srachamim profile image
SRachamim • Edited

You asked for more type-safe TypeScript, so my response is: look for more functional solutions and you'll get more type safety.

Thread Thread
 
adam_cyclones profile image
Adam Crockett 🌀 • Edited

I asked for less typesafe, but still typescript, I want to make typescript not care about non declared globals as the description states.

This is for a very unusual edge-case