Attempting to create a function with a return type called UnpackedValuesOnly
, which can dynamically ascertain the type of a "packed" value K
without requiring explicit user input for defining what K
is.
Here's my closest attempt so far:
//assume this class has practical use cases
class PackedValue<T> {
value: T
constructor(value: T) {
this.value = value
}
}
//This code snippet represents my effort to unpack the type of a PackedValue dynamically
type UnpackedValuesOnly<T, K = any, K2 = any, K3 = any, K4 = any, K5 = any> = {
[P in keyof T]: T[P] extends PackedValue<K>
? K
: T[P] extends PackedValue<K2>
? K2
: T[P] extends PackedValue<K3>
? K3
: T[P] extends PackedValue<K4>
? K4
: T[P] extends PackedValue<K5>
? K5
: UnpackedValuesOnly<T[P], K, K2, K3, K4, K5>
}
const unpackObj = <T, K = any, K2 = any, K3 = any, K4 = any, K5 = any>(toUnpack: T): UnpackedValuesOnly<T, K, K2, K3, K4, K5> => {
//implementation details are not important, assumes non-packed values remain unchanged and packed values are unpacked
return {} as any as UnpackedValuesOnly<T, K, K2, K3, K4, K5>
}
const foo = {
a: 'hello',
b: new PackedValue([ 1, 3 ]),
c: new PackedValue('asdf')
}
const bar = unpackObj<typeof foo, number[]>(foo)
//string type
bar.a
//number[] type
bar.b
//any type
bar.c
The specified approach presents a few significant drawbacks:
- There is a limited number of allowed
PackedValue
types, currently set at 5 - Users need to explicitly define all used
PackValue
types when callingunpackObj
; otherwise, those types will default to anany
type and lose compiler validation
Is there a method to write UnpackedValuesOnly
such that the following example code would enable the compiler/linter to report the correct types by automatically determining the PackedValue
type?
const bar = unpackObj(foo) // or perhaps unpackObj<typeof foo>(foo)
//string type
bar.a
//number[] type
bar.b
//string type
bar.c