A custom type is something like this: Object, expects n number of types. Types can be unions. Map -> a type that expects 2 types. Map<T, P> T is a union of types P is a union of types ParticularMap -> Map<Int, String> ```typescript CustomeMap = Map<K extends SomeBaseUnion, V extends SomeUnion> CustomMap<UInt, SomeThing> ``` ArrayMap -> Expects 2 types. [] -> length 2 ArrayMap -> ArrayMap<UnionOfUints, Array<Numeric>> ```typescript type ScalarUnion = ScalarTypeName[] type MapKeyUnion = [ "UInt", "UInt8", "UInt16", "UInt32", "Int", "Int8", "Int16", "Int32", "String" ] type CustomArray<T extends AnyUnion = AnyUnion> = { items: RecursiveArrayUnion<T> } type CustomMap<TKey extends MapKeyUnion = MapKeyUnion, TValue extends AnyUnion = AnyUnion> = { key: RecursiveArrayUnion<TKey>, value: RecursiveArrayUnion<TValue> } type AnyUnion = (CustomArray | CustomMap | ScalarUnion)[] | ScalarUnion; type Union<T> = T[keyof T]; type RecursiveArrayUnion<T> = { [K in keyof T]: T[K] extends Array<infer U> ? UnionOfArray<U> : T[K]; } type UnionOfArray<T> = T extends any ? T extends Array<infer U> ? Union<U> : T : never; // Example type CustomType<T extends AnyUnion> = { types: RecursiveArrayUnion<T> } type ArrayMap = CustomType<[ [ "UInt", "UInt8", "UInt16", "UInt32", ], CustomArray<[["UInt", "Int"]]>, ]> interface ParticularArrayMapDefiniton extends ArrayMap { types: ["UInt32", { items: ["Int"] }] } export const scalarTypeSet = { UInt: "UInt", UInt8: "UInt8", UInt16: "UInt16", UInt32: "UInt32", Int: "Int", Int8: "Int8", Int16: "Int16", Int32: "Int32", String: "String", Boolean: "Boolean", Bytes: "Bytes", BigInt: "BigInt", BigNumber: "BigNumber", JSON: "JSON", }; export type ScalarTypeName = keyof typeof scalarTypeSet; ```