How to create dynamic number union in typescript

Hey guys, so I'm starting to think this isn't even possible (especially with the comments chatGPT added saying its not possible lol) so basically I have a function, which im going to call 'test' test receives a generic that is expected to be a union type. We will call this type R For the return type of 'test', it is sending back a tuple. This tuple consists of 2 objects of 2 different types. [R, X] Essentially, I need help solving for X. I need X to be a union type of numbers starting at 0 and incrementing until the length of the unions are equal. Is there any way to potentially accomplish this? It is in essence the final thing I need to complete the little project I've been working on today which is just a 'better' enum
type Role = 'User' | 'Admin' | 'Owner';
type RoleNum = 0 | 1 | 2;

//In the first example here, we are defining a 'Role' type and a generic R. Ideally we would be able to break down the union type passed into R to create the 'RoleNum' type. Instead of parameters, the data is passed in directly as the type.
function test<R extends string>(): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}



//In this example, we nix the R type all together and pass in the hard coded string values. This could be better because it includes an array that can be iterated through
function test(...role: string[] ): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}
type Role = 'User' | 'Admin' | 'Owner';
type RoleNum = 0 | 1 | 2;

//In the first example here, we are defining a 'Role' type and a generic R. Ideally we would be able to break down the union type passed into R to create the 'RoleNum' type. Instead of parameters, the data is passed in directly as the type.
function test<R extends string>(): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}



//In this example, we nix the R type all together and pass in the hard coded string values. This could be better because it includes an array that can be iterated through
function test(...role: string[] ): [Record<R, number>, RoleNum] {
//const [first, ...rest] = params;
//const enumerated = typeof first === 'boolean' ? first : undefined;
const result = {} as Record<R, number>;
const unionType: number[] = [];


return [result, unionType];
}
8 Replies
Sybatron
Sybatron2y ago
This just sounds like you wanna make enum with extra steps
MagerX
MagerXOP2y ago
That is precisely what I'm doing but without the drawbacks that enum has with the weird generation patterns that it has. Not that I expect it to take off or anything, I'm just curious if A) it can be done and B) can I do it decently
Sybatron
Sybatron2y ago
just generate an object not sure why you need the whole array stuff but dont think you can generate that object with const values inside so it wont be as enum as you need to constantly think that you shouldnt change the values inside that object
MagerX
MagerXOP2y ago
tbh this is the last step i need, support for incremental enums instead of definition
const [Roles, _Role] = makeEnum("User", "Admin", "Owner");
const [Roles, _Role] = makeEnum("User", "Admin", "Owner");
Conceptually, I just need to figure out how to count the total params and then create a union with an integer for each param. Once I figure that out, I will be finished with the 'difficult' aspects of it and its purely for intellisense purposes at this point as well. Its functioning in javascript great
Sybatron
Sybatron2y ago
why would you want to count them all, the params are array you can add them to an object via foreach
MagerX
MagerXOP2y ago
Because the incremental Enum has a number value associated with each item rather than a text value, so in order to provide that functionality, I need to figure out how to generate a dynamic number union right now
const [Roles, _Role] = makeEnum("User", "Admin", "Owner");
const [Roles, _Role] = makeEnum("User", "Admin", "Owner");
Provides the exact shape I need, Roles.User = 0, Roles.Admin = 1 etc. The problem lies in utilizing the enum atm,
function enumTest(enum: Roles /*empty union type*/) {

}
function enumTest(enum: Roles /*empty union type*/) {

}
Sybatron
Sybatron2y ago
unions are static types types in typescript are static
MagerX
MagerXOP2y ago
yeah thats pretty much been the wall im walking into today
Want results from more Discord servers?
Add your server