1

So I want to create a type that maps dynamically the properties of the passed type to an array of key properties. The idea is to create a type validation that only allows passing a name that belongs to the class or sublcasss. Example:

class User {
  id:number;
  email:string;
  profile: Profile;
}

class Profile {
  id:number;
  name:string;
}

// Expecten outcome for this would be ['id,'email','profile.id', 'profile.name']
type arrayOfProperties = MyFlattenType<User>;

I've tried different approaches but none of them work as intended. I'm having trouble figuring out how to return the array since most of the reading that I made all the examples returned an object.

  • I'm having trouble with your expected outcome. You want the *type* to be `['id,'email','name','profile.id', 'profile.name']`? So it's an ordered tuple? If so, how should the order be determined (keeping in mind that order of object keys is not reliably observable in TypeScript)? Why is `'name'` in there by itself? Is that a typo? – jcalz May 04 '22 at 03:56
  • More questions: Is there some reason you're using `class` instead of `interface` here? The example classes don't initialize their properties, which isn't great... unless you want to bring up issues of property initialization, I'd suggest either initializing them or using `interfaces` instead. You don't initialize your `arrayOfProperties` variable, so it won't compile cleanly even if you define the type `MyFlattenType`... what do you want to do there? – jcalz May 04 '22 at 03:59
  • 1
    Does [this approach](https://tsplay.dev/mb0MEw) meet your needs or am I missing something? – jcalz May 04 '22 at 04:00
  • Yes, it is a typo, thanks for noticing. Essentially I have it in a class since they represent database entities and I want to have a method that accepts parameters only of that type, so it doesn't allow the user to pass names that don't belong to a database entity. I'm not trying to initialize anything I only want to assure that the property belongs to the classes. Regarding the approach, I tried and it solves the problem. Thanks for the answer. Just one doubt what does the type Prev does exactly? – joseFrancisco May 04 '22 at 05:17
  • 1
    It's a recursion limiter because sometime people will have circular/recursive data structures (e.g., `Profile` points back to `User` as well) and you don't want the compiler to explode trying to compute `'profile' | 'profile.user' | 'profile.user.profile' | 'profile.user.profile.user' | ...` ad infinitum. See the linked q/a pair for more information about how the `Leaves` type works. – jcalz May 04 '22 at 14:06
  • Ok, thanks for the description. Can you post your comment as an answer so I can mark it as accepted? – joseFrancisco May 04 '22 at 17:41
  • @jcalz I'm when using this type you suggested I'm getting an IDE error from visual studio code saying "Type instantiation is excessively deep and possibly infinite.ts(2589)". Do you know how to work around this? – joseFrancisco May 05 '22 at 00:25
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244484/discussion-between-josefrancisco-and-jcalz). – joseFrancisco May 05 '22 at 00:36

0 Answers0