0

Let's say I have a class User:

export class User {
  constructor(
    userID?: number,
    state?: 'In' | 'Out' | 'Break' | 'Lunch', // for example, but there are more...
    stateVal?: 1 | 2 | 3 | 4,
  ) {}
}

The purpose of stateVal is to make sorting by state to be in a specific order and not alphabetical, i.e. by default it sorts by alphabetical which can result in undesired order->

(default, alphabetical)
(1) Break
(2) In
(3) Lunch
(4) Out

(desired order)
(1) In
(2) Break
(3) Lunch
(4) Out

That way, if I sort this stateVal rather than state, I can get the order I want.

Overall, what happens is, I get a list of users from a RESTful API, then I must add in a stateVal by looping through each User and adding stateVal manually (since stateVal is not provided by the server).

BUT can this be done at the class level?

I'm wondering:

Is it possible to automatically map the state property to trigger stateVal to be a value depending on itself?

i.e.

If state is 'In', automatically set stateVal to 1 -- from a Class point of view? Somehow enforce this logic?

Bobby_Cheh
  • 689
  • 5
  • 11
  • 1
    Maybe something like [this](https://tsplay.dev/WK7k8W)? If that works for you I could possibly write up an answer; if not, could you describe the unsatisfied use cases? Also, your class has errors, you can't put an optional parameter before a required one. – jcalz Nov 05 '21 at 19:52
  • Thanks for the heads up, fixed that, they are all supposed to be optional. So your method works except that accessors like getters are required and this throws all sorts of errors in my app. And apparently this has been an ongoing issue, to provide a `?` like so: `get stateVal?() { ... }` which would be the key to me being able to use this method! [Github issue here](https://github.com/microsoft/TypeScript/issues/14417) – Bobby_Cheh Nov 05 '21 at 21:30
  • I mean it can be required but possibly `undefined`. But in any case it’s not really functionality of the instance so much as the class prototype, so a `getStateVal()` should be equivalent. I’m sure there’s a workaround anyway. – jcalz Nov 05 '21 at 21:43
  • Can you demonstrate with a [mre] the sort of errors you're talking about so I can see them? And do they persist with [this code](https://tsplay.dev/WG6nVm)? – jcalz Nov 06 '21 at 02:58
  • Use a getter. Or even simpler, just define your sort comparison not to work alphabetically, you shouldn't need a `.stateVal` on your objects at all. [Define the order of "states" separately](https://stackoverflow.com/q/13304543/1048572). – Bergi Nov 06 '21 at 05:28
  • @jcalz [minimal example](https://www.typescriptlang.org/play?#code/MYewdgzgLgBNCGUCmA1eAbCMC8MDeAsAFAykwBEAkmOQFwwCMANMWRQPICuUdMATCxJlyAIQBOSeAGteAZkFtyAGU5hgAC14AWYgF8Y8LKEhQA3MSgBPAA5IYAZSiI7uKUksgAZjCu2vcJ2Q0THMiYmJgdEMsAFUIJDF8VjJjaDFOYCgQMQAKZLZSa04AI3QAS2AA5wB+ekdnBQLCkvLKsoATWpgwTgBbYoT8mABKfBhdcKFSAHMkWAQgjBzRwimCiShOMTAfdTKIADoFu2qqxcwAbSg9w+OAXRh6VXakTzKwJHbQtgmiX+JPKpMmVwDBPHMNHEEhBlvQoWILg88DAAPQomBIAAeBwM1jKMGAGHQQw2Wx2F1WTVIx3oAHJqLTGk0OvRmENdEwkms2DSYLSuFBGUM2Cz+Ezxnc9JNAWooCCdugQPB2vCACKIeDLLlsVKwTjxMQQOEGxE4MEQ9TwmHDUK6IA). I started seeing this error everywhere in my app – Bobby_Cheh Nov 08 '21 at 17:04
  • For some reason the TS playground links eat up most of the characters for the comment. Anyway I'm basically never using `new` to trigger the constructor of the classes which I think is why I'm having this issue. I'd have to figure out how I can fetch from an API call a list of users and instantiate them into classes using `new` so that it's actually calling the constructor. I'm essentially just using the classes as a template, rather than a functional class if that makes sense. Maybe that is my problem. – Bobby_Cheh Nov 08 '21 at 17:10
  • 2
    Yes, you should use the class constructor if you want to get class prototype behavior. It really seems like you shouldn't be trying to get `stateVal` "property" on your `User` objects anyway; instead you should just have some external function, like [this](https://tsplay.dev/WoJqPm). – jcalz Nov 08 '21 at 19:44
  • So, do you want this turned into an answer? Or is there some outstanding issue not already addressed? – jcalz Nov 09 '21 at 15:17
  • Yes that would be great. I think I'm gonna go with the external function to get stateVal due to how I'm using classes in my app. It makes more sense but I'm gonna have to refactor how the sorting method was setup on my end since it was meant to be a generic function that just takes any array of objects and the property string to sort by as params. – Bobby_Cheh Nov 09 '21 at 16:28
  • @Bobby_Cheh Don't pass a property string, pass an accessor function. Can be something simple like `x => x.name`, or something like `user => stateVals[user.state] ?? 0` – Bergi Nov 09 '21 at 16:50
  • @Bergi yeah you're right, I will do this instead-- I'm now realizing the advantage of this. – Bobby_Cheh Nov 09 '21 at 17:11

0 Answers0