Description
Problem
So, let's suppose that you created a variable in this way const user = fromJS({ profile: { name: 'username' } });
, so the main problem in that this variable has a type any
which makes harder to find what this variable really is, one example is if someone just make a shadowing in that constant using the toJS()
method, that will cause a lot of errors and things will get harder to know what type it has.
There is also another problem, which is to infer the types of subarrays and subobjects (like the name inside the profile), which will requires recursive type, something reeaaly weird to do
My local fix
Note: this solution is a huge hack and could cause troubles in the type system, keep that in mind
So to infer the types in a recursive way for objects (keeping the same type for all the rest), here is a huge hack that I made and fixed the type inference problem for me
interface ImmutableMap<T> extends Map<string, any> {
get<K extends keyof T>(
name: K,
): T[K] extends object
? T[K] extends any[]
? List<T[K]>
: ImmutableMap<T[K]>
: T[K];
getIn<K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(
path: [K1, K2, K3],
): T[K1][K2][K3] extends object
? T[K1][K2][K3] extends any[]
? List<T[K1][K2][K3]>
: ImmutableMap<T[K1][K2][K3]>
: T[K1][K2][K3];
getIn<K1 extends keyof T, K2 extends keyof T[K1]>(
path: [K1, K2],
): T[K1][K2] extends object
? T[K1][K2] extends any[]
? List<T[K1][K2]>
: ImmutableMap<T[K1][K2]>
: T[K1][K2];
getIn<K1 extends keyof T>(
path: [K1],
): T[K1] extends object
? T[K1] extends any[]
? List<T[K1]>
: ImmutableMap<T[K1]>
: T[K1];
toJS(): T;
equals(obj: any): boolean;
}
this solution doesn't not cover everything, but fixed my problem and if something is missing, I can just add it