-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
I think TypeScript's complexity is a symptom of the larger problem: JavaScript interfaces having very weird shapes, taking weird shapes of inputs and creating weirdly-shaped values. A big reason why TypeScript evolved to become so complex, and why it adapted conditional and mapped types, is it needed to be able to type these weirdly-shaped, interfaces which have already existed in the first place.
What I mean by "weird shapes" is, consider `util.promisify`. It converts a function which takes a callback into one which returns a promise. Except that input function which takes a callback can take any number of arguments before said callback, and then the returned function takes the same number of arguments. Furthermore, if the input function contains the field `util.promisify.custom`, `util.promisify` will completely alter its behavior and instead return the value of said field. As a result of all these edge cases, `util.promisify` has a massive, 77+LOC long type signature (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/mast...). And it isn't nearly the worst offender, considering there aren't even any conditional or mapped types here.
Now, I still think TypeScript's complex type system itself is an almost universally good, because the alternative is simply not being able to type-check these interfaces, dealing with `any` types and type errors. I say "almost", because it does encourage API builders to create these super-dynamic weird interface shapes. But, remember, these weird shapes existed before TypeScript, and I'm of the opinion that "useful feature which encourages bad things" is better than "no useful feature but no encouraging bad things" (I believe languages should have more freedom than less, prefer Rust and PureScript over Go and Elm, etc.)
But these weirdly-shaped types are bad. Because, even with TypeScript's awesome type system managing to 100% express them, they still cause problems:
- They make the JIT less effective and interpreter less efficient, because it cannot speculate on a value whose shape is constantly changing, or optimize a function which constantly provides different-shaped inputs and returns different-shaped outputs.