4 ms·
I quite like Typescript's approach here, which is (a) to model that metaprogramming as much as possible with metaprogramming of types, and (b) to always give yo
by MrJohz 3y ago
I quite like Typescript's approach here, which is (a) to model that metaprogramming as much as possible with metaprogramming of types, and (b) to always give you an escape hatch so you can wrap type unsafe metaprogramming in a type safe layer.
For example, I recently wrote a function that takes an arbitration nested object and a list of paths through that object (e.g. "path.to.object"), and does things with the data found at those paths. For (1), I could write a type that, given an object type, would return all the possible allowed paths as types, basically preventing the function from being used correctly (and it already has helped me catch a few typos here and there). So now func({foo:...}, "bar") is disallowed directly at the type system.
But working with those exact types inside the function would have been too complicated, so I also did (2): inside the function, I just treated as the strings as normal strings (which, to the runtime, they are!) and did normal JavaScript metaprogramming to get arbitrary keys from arbitrary objects. I then have less type safety inside the function, but I can test that part more, while still leaving the caller of the function with the exact correct types.
In fairness, there are other ways to solve the same problem in other languages, with similar type safety. And JavaScript natively is not that high up on the metaprogramming scale. But I'm always impressed in Typescript how much a powerful type system and metaprogramming can dovetail into each other.