1

I have an object of this type

interface Obj {
  key1: SubType1;
  key2: SubType2;
}

Where SubType1 and SubType2 are all given.

type Name = "LOL" | "HAHA";
type Statu = "Active" | "Inactive";
interface SubType1 {
  key: {
    name: Name;
  };
}
interface SubType2 {
  status: Statu;
}

I implemented a function which takes the object and other object called transformObject as its argument. The transform object has a recursive generic type so it knows the structure of the object provided. The point of this function is to conveniently traverse the object with transformObject and change a specific field of that object while conforming to the original type.

Here is the imlementaion

type MappedTransform<T> = {
  [K in keyof T]?: MappedTransform<T[K]> | ((params: T[K]) => T[K]);
};

function foo<T>(obj: T, transformObject: MappedTransform<T>) {
  // I omit the implementaion details for this function to make the question simple
}

foo(obj, {
  key1: {
    key: {
      name: "HAHA" //  here the value that `name` field can change to can only be 
    // either `HAHA` or `LOL` because `MappedTransform` enforces that it has to be of the original type
    }
  }
});

My question is, if I want to use another type to lock where transformObject can reach, in other words, ideally if I do this

foo<Obj, Name>(obj, transformObject);

the transformObject can only be at the level of Name type, not on any other types e.g. Status.

so this should give me error because status is not of type Name, its type is Status

foo<Obj, Name>(obj, {
  key2: {
    status: 'Inactive' //  this should give me error since it is not of the type `Name` provided in the generic
  }
});

https://codesandbox.io/s/ts-recursive-function-tmo11?file=/src/index.ts

This is a live demo you can play with

Joji
  • 4,703
  • 7
  • 41
  • 86
  • Is [this](https://tsplay.dev/DWKQZN) what you're looking for? I think there might be lots of edge cases and I'm not sure what you're really trying to accomplish. If that doesn't work maybe you can elaborate about the use case – jcalz Nov 14 '20 at 02:20
  • @jcalz actually what I am trying to achieve is based on this question. https://stackoverflow.com/questions/64708485/typescript-how-do-i-add-proper-typing-to-this-function-with-object-entries where actually you answered it and I hope I can get a follow up on that because you said you would write it up later... I mentioned the use case in the post. I didn't want to write too much details in the post because that might overwhelm people and make them less likely to answer the question.... – Joji Nov 14 '20 at 02:33
  • Both in that question and this question I'm not sure enough about the use case to answer with certainty; if I have time I'll come back here and there and write up an answer using my current understanding of the questions, but it would be good if I understood more what's going on. Could you try the solutions I gave in this and the other one and see if they work for your use cases? Or tell me if they don't? – jcalz Nov 14 '20 at 03:12
  • Hi thanks for the replies. Yes I looked at the solution you posted on here. It is working as intended. but as you said there are some edge cases that you didn't cover. could you write an answer for how you arrived at this solution so I can learn from it. Thanks! – Joji Nov 14 '20 at 03:49

0 Answers0