3

Let's say I can have any of the following values in typescript and I pass it to a function:

[1, [2,3,4], 5]

[1, 2, [3,4,5]]

How can I type the function and the ReturnType of the function so I can preserve all the type information inferred from the values I put in?

I'd like to access the exact same shape out which I put in.

The solution might use a custom (recursive) type, not necessarily tuple/array.

type MyContainerT<???> = ???

let myContainer : () => MyContainerT
let v = myContainer(1, myContainer(2,3,4), 5) // passing in arbitrary, recursive-shaped value
let r = f(v) 
                             
// r SHALL HAVE (INFER) a type like 
// MyContainerT<1, MyContainerT<2,3,4>, 5>, but this is just an idea

function f<???>(v: MyContainerT<???>): MyContainerT<???>{
    // here to access types recursively
    return v // return whatever, but keep EXACT shape
}
PEZO
  • 441
  • 4
  • 14
  • I’m not really following. Assuming you do pass array literals into your function, what do you want the output type to look like? Saying “exact same shape” isn’t quite specific enough… could you post a [mre] showing some particular input/output type mappings? – jcalz Jan 08 '22 at 18:51
  • @jcalz sorry if it is not clear, Thanks for asking. f([1,2,[3,4,5]) shall have the type of [1,2,[3,4,5]] instead of (number|number[])[], any depth. Funs act like a boundary. How can you create a recursive type and pass through a fun so you can access the same recursive type -you have as input- on the output side, while you may also “unbox” this recursive type and you can do stuff with its parts/elements. List: all items have same type. Tuple: items types may differ, but lenght must be set. I need different types without explicitly setting the length (I want to infer length/shape) – PEZO Jan 08 '22 at 20:14
  • @jcalz i think you can infer that a type is [number, number], 2 length tuple via “[1,2] as const” or [number,[number,number]] via “[1,[2,3]] as const”. But what if you dont know which one you get, but you want to handle both AND you want to pass it through a function. Maybe it is 2 separate questions (not sure) and f only have to give back T if it received T, I am just unsure about the whole due the recursive thing going on AND I am not sure how to handle these different shape of tuples (or MyContainers) by inferring. – PEZO Jan 08 '22 at 20:33
  • So you might be looking for [ms/TS#30680](https://github.com/microsoft/TypeScript/issues/30680); there are ways to give hints to the compiler to infer tuple types and literal types, although they’re a bit weird. Is that what you’re looking for? Or am I missing something? – jcalz Jan 08 '22 at 20:35
  • Does [this approach](https://tsplay.dev/NnX2VW) work for you? If so I can write up an answer; if not, let me know what I'm missing, preferably by [edit]ing the question with a [mre] that demonstrates exactly what you're looking for. – jcalz Jan 09 '22 at 01:44
  • @jcalz Please give me a couple of days and will get back! Thanks for your ideas! – PEZO Jan 09 '22 at 08:59
  • @jcalz In your example type of v is [1, (2 | 3 | 4)[], 5, [[6]][]] below TS4.4, can you please elaborate why is that? I'll try update my project and come back. So far so good. – PEZO Jan 12 '22 at 05:21
  • I wouldn't know without extra research, which seems out of scope for the question as asked... if you need something that works in an older version of TS then you might want to [edit] the question to specify the version requirements (although I wouldn't guarantee I could address it). – jcalz Jan 12 '22 at 14:37
  • @jcalz Your solution is flawless for one of my use cases, but I have found another use case which might need more tweaks. This might be complicated so I think you can just add your answer here (please let me know how you found it out if you can) and I am going to create a new question for the another case. – PEZO Jan 12 '22 at 15:46

0 Answers0