fully-react
Version:
React Server for Vite
197 lines (159 loc) • 4.83 kB
text/typescript
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;
}