import { Project, FileEntry } from 'lib/project' export type IndexLoaderData = { code: string | null project?: Project file?: FileEntry } export type FileLoaderData = { code: string | null project?: FileEntry | Project file?: FileEntry } export type HomeLoaderData = {} // From the very helpful @jcalz on StackOverflow: https://stackoverflow.com/a/58436959/22753272 type Join = K extends string | number ? P extends string | number ? `${K}${'' extends P ? '' : '.'}${P}` : never : never type Prev = [ never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[] ] export type Paths = [D] extends [never] ? never : T extends object ? { [K in keyof T]-?: K extends string | number ? `${K}` | Join> : never }[keyof T] : '' type Idx = K extends keyof T ? T[K] : number extends keyof T ? K extends `${number}` ? T[number] : never : never export type PathValue< T, P extends Paths > = P extends `${infer Key}.${infer Rest}` ? Rest extends Paths, 1> ? PathValue, Rest> : never : Idx export type Leaves = [D] extends [never] ? never : T extends object ? { [K in keyof T]-?: Join> }[keyof T] : '' // Thanks to @micfan on StackOverflow for this utility type: // https://stackoverflow.com/a/57390160/22753272 export type AtLeast = Partial & Pick export function isEnumMember>( v: unknown, e: T ) { return Object.values(e).includes(v) } // utility type to make all *nested* object properties optional // https://www.geodev.me/blog/deeppartial-in-typescript export type DeepPartial = { [P in keyof T]?: T[P] extends object ? DeepPartial : T[P] } /** * Replace a function's return type with another type. */ export type WithReturnType any, NewReturn> = ( ...args: Parameters ) => NewReturn /** * Assert that a function type is async, preserving its parameter types. */ export type AsyncFn any> = WithReturnType< F, Promise >