DEV Community

Beyond Type Safety: making TypeScript smarter by Building a Runtime Picker

HichemTech on December 14, 2024

Disclaimer Hey, before we get started, let me clarify something: while I’ll be talking a lot about my package, ts-runtime-picker, this isn’t a pr...
Collapse
 
ruudt profile image
Ruud Walraven

You ingenuity is much appreciated, I like tinkering and making new things too! The frustrating thing for me though is that there's always someone who thought of my ideas earlier. That doesn't reduce the feat on your end, and there may be users that need a as lightweight as possible solution that need your library. But I do want to point iut Typia. It's capable of much more then just pruning, including checking the correct types of the allowed properties.

import typia from "typia";

type User = {
  name: string;
  age: number;
};

const input = { name: "Anna", age: 24, extra: "remove me" };

const user = typia.misc.assertPrune<User>(input);

console.log(user); // { name: "Anna", age: 24 }
Enter fullscreen mode Exit fullscreen mode

There are some other types of libraries that can also validate unit like Zod, but that isn't really based on TypeScript types.

Collapse
 
hichemtab-tech profile image
HichemTech

Thanks for tips, I'll definitely check them

Collapse
 
kasir-barati profile image
Mohammad Jawad (Kasir) Barati • Edited

Hmm, to me these approaches sound a bit over engineering. I mean yeah we need to sanitize incoming data from our client but that is just about separation of concerns and each layer needs to play its role. When a method/function says I only accept int as input you should not be sending it a string. And if that string comes from user input, someone in the middle needs to sanitize and validate data.

IMO the idea of class-validator, class-trasformer + DTO layer is a very clean architecture for your software.

Do the validation once, not at each layer. Am I forgetting something 🧐?

@ruudt, @hichemtab-tech.

Collapse
 
petec profile image
PeteC

I wrote a similar function that doesn't use compile-time manipulation of the source. The difference is that you do need to specify an array of field names to copy, but the list is type-checked against the interface that you're copying to.

I think your article is (or should be) more about the power of babble plugins than Typescript per se, since you're not achieving the result purely from using Typescript. It could also do with fewer emojis!

Collapse
 
hichemtab-tech profile image
HichemTech

Thanks for the observation ^.^

Collapse
 
mavrik profile image
ArtemM

I'm curious what happens with nested interfaces? What if my top level interface contains another interface? Does it pick props recursively? What if it is a circular nesting?

A cool idea though. I have so many things in my mind how typescript metadata could improve runtime.

Collapse
 
hichemtab-tech profile image
HichemTech

Well that's a good idea, I didn't think of that, I'll fix it in next version thanks

Collapse
 
deadreyo profile image
Ahmed Atwa

Can you share the logic behind the package?

Collapse
 
hichemtab-tech profile image
HichemTech

Yes ofcs you can check the repository here : ts-runtime-picker - ts-transformer

Collapse
 
namhtpyn profile image
namhtpyn • Edited

You should have mentioned vite some where in this post as this obviously will not work if your project is not using vite.

Collapse
 
ada_e89c9efb7eb2ce2c6c2f3 profile image
Ada

Now what happens if you create a decorator that takes an ordered list of interfaces/classes/types corresponding to the function/method arguments so that you don't have to change function bodies to perform this work?
I'm thinking AOP style validation/input filtering. Should reduce cognitive load on users of the library, and anyone coming in to the code later.
(Something like this would have reduced a massive amount of upcoming effort on my plate)

Collapse
 
huh_hmh_1c5f4812c8caecef7 profile image
Huh Hmh

Much of the same and more propagated type safety can be insured through Typebox

Collapse
 
omril321 profile image
Omri Lavi

Thanks for sharing! As other mentioned, there may be other tools that solve this problem. But I really like your approach and how you learned by solving a real problem 💪