export type DeepReadonly = T extends any[] ? DeepReadonlyArray : T extends object ? DeepReadonlyObject : T; type NonFunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; interface DeepReadonlyArray extends ReadonlyArray> {} type DeepReadonlyObject = { readonly [P in NonFunctionPropertyNames]: DeepReadonly; }; type TypeName = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends undefined ? "undefined" : T extends Function ? "function" : "object";