UNPKG

fully-react

Version:
197 lines (159 loc) 4.83 kB
export type NoInfer<T> = [T][T extends any ? 0 : never]; export type IsAny<T, Y, N> = 1 extends 0 & T ? Y : N; export type IsAnyBoolean<T> = 1 extends 0 & T ? true : false; export type IsKnown<T, Y, N> = unknown extends T ? N : Y; export type PickAsRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>; export type PickAsPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>; export type PickUnsafe<T, K> = K extends keyof T ? Pick<T, K> : never; export type PickExtra<T, K> = { [TKey in keyof K as string extends TKey ? never : TKey extends keyof T ? never : TKey]: K[TKey]; }; export type PickRequired<T> = { [K in keyof T as undefined extends T[K] ? never : K]: T[K]; }; export type Expand<T> = T extends object ? T extends infer O ? { [K in keyof O]: O[K] } : never : T; export type UnionToIntersection<U> = ( U extends any ? (k: U) => void : never ) extends (k: infer I) => any ? I : never; type Compute<T> = { [K in keyof T]: T[K] } | never; type AllKeys<T> = T extends any ? keyof T : never; export type MergeUnion<T, Keys extends keyof T = keyof T> = Compute< { [K in Keys]: T[Keys]; } & { [K in AllKeys<T>]?: T extends any ? K extends keyof T ? T[K] : never : never; } >; export type Values<O> = O[ValueKeys<O>]; export type ValueKeys<O> = Extract<keyof O, PropertyKey>; export type DeepAwaited<T> = T extends Promise<infer A> ? DeepAwaited<A> : T extends Record<infer A, Promise<infer B>> ? { [K in A]: DeepAwaited<B> } : T; type DynamicParamIndicator = ":"; export type PathParamMask<TRoutePath extends string> = TRoutePath extends `${infer L}/${DynamicParamIndicator}${infer C}/${infer R}` ? PathParamMask<`${L}/${string}/${R}`> : TRoutePath extends `${infer L}/${DynamicParamIndicator}${infer C}` ? PathParamMask<`${L}/${string}`> : TRoutePath; export type Timeout = ReturnType<typeof setTimeout>; export type Updater<TPrevious, TResult = TPrevious> = | TResult | ((prev?: TPrevious) => TResult); export type PickExtract<T, U> = { [K in keyof T as T[K] extends U ? K : never]: T[K]; }; export type PickExclude<T, U> = { [K in keyof T as T[K] extends U ? never : K]: T[K]; }; export function last<T>(arr: T[]) { return arr[arr.length - 1]; } function isFunction(d: any): d is Function { return typeof d === "function"; } export function functionalUpdate<TResult>( updater: Updater<TResult>, previous: TResult, ) { if (isFunction(updater)) { return updater(previous as TResult); } return updater; } export function pick<T, K extends keyof T>(parent: T, keys: K[]): Pick<T, K> { return keys.reduce((obj: any, key: K) => { obj[key] = parent[key]; return obj; }, {} as any); } /** * This function returns `a` if `b` is deeply equal. * If not, it will replace any deeply equal children of `b` with those of `a`. * This can be used for structural sharing between immutable JSON values for example. * Do not use this with signals */ export function replaceEqualDeep<T>(prev: any, _next: T): T { if (prev === _next) { return prev; } const next = _next as any; const array = Array.isArray(prev) && Array.isArray(next); if (array || (isPlainObject(prev) && isPlainObject(next))) { const prevSize = array ? prev.length : Object.keys(prev).length; const nextItems = array ? next : Object.keys(next); const nextSize = nextItems.length; const copy: any = array ? [] : {}; let equalItems = 0; for (let i = 0; i < nextSize; i++) { const key = array ? i : nextItems[i]; copy[key] = replaceEqualDeep(prev[key], next[key]); if (copy[key] === prev[key]) { equalItems++; } } return prevSize === nextSize && equalItems === prevSize ? prev : copy; } return next; } // Copied from: https://github.com/jonschlinkert/is-plain-object export function isPlainObject(o: any) { if (!hasObjectPrototype(o)) { return false; } // If has modified constructor const ctor = o.constructor; if (typeof ctor === "undefined") { return true; } // If has modified prototype const prot = ctor.prototype; if (!hasObjectPrototype(prot)) { return false; } // If constructor does not have an Object-specific method if (!prot.hasOwnProperty("isPrototypeOf")) { return false; } // Most likely a plain Object return true; } function hasObjectPrototype(o: any) { return Object.prototype.toString.call(o) === "[object Object]"; } export function partialDeepEqual(a: any, b: any): boolean { if (a === b) { return true; } if (typeof a !== typeof b) { return false; } if (isPlainObject(a) && isPlainObject(b)) { return !Object.keys(b).some((key) => !partialDeepEqual(a[key], b[key])); } if (Array.isArray(a) && Array.isArray(b)) { return ( a.length === b.length && a.every((item, index) => partialDeepEqual(item, b[index])) ); } return false; }