UselessPickles / ts-enum-util

Strictly typed utilities for working with TypeScript enums
MIT License
228 stars 6 forks source link

Make the library tree shakable #31

Open MickL opened 3 months ago

MickL commented 3 months ago

Using import { $enum } from "ts-enum-util"; will always import the full library even tho just one function of it is used.

Preferable it would be possible to import just what is needed, e.g.:

{ getValues } from "ts-enum-util";

enum ABC = {
    B = 3,
    A = 1,
    C = 2
}

// defined order is retained: [3, 1, 2]
const values = getValues(ABC);

Motivation: Both in the browser as in serverless (edge) functions bundle size is very important.

UselessPickles commented 3 months ago

I'll have to think on this for a while and experiment when I have some extra time, but my gut reaction is that this may not be possible, or the ways it could be possible may be too big of a downgrade in consistency and ease of use. This would be major rewrite of the entire library with a completely different TBD approach of how to get the generic types working as desired, so don't hold your breath for this. I will think about it and play around with some ideas when I have time.

This not just a library of individual functions that could be individually imported. A majority of this library is an EnumWrapper class whose constructor processes/caches some info about the enum, then has several methods. Then there's the $enum() function itself that that caches one instance of the wrapper per enum via a WeakMap, and and is needed to properly type the EnumWrapper. Much of this is intentionally designed this way for runtime optimization so you can simply use the library without worrying about caching and reusing instances of EnumWrapper, etc.

From a runtime implementation perspective, it's easy to imagine ways I could break this class up into an object of cached data per enum in the WeakMap and a collection of functions that all depend on that same object of cached data. However, the majority of the complexity of this library is in the generic types that make it all type-safe. I currently rely on the $enum() to set the type params of the EnumWrapper class correctly, which are then further referenced in generic methods of the class to enforce/infer types of additional params correctly. I would need to rethink the generic types from the ground up and come up with very different solutions to the problems that I specifically solved with the current pattern of the $enum() function returning a class instance that has many methods. It may or may not be feasible to come up with a non-class-based solution that is easy to use.