@solid-primitives/utils
Version:
A bunch of reactive utility types and functions, for building primitives with Solid.js
90 lines (89 loc) • 3.92 kB
TypeScript
import type { Accessor, Setter } from "solid-js";
export type { EffectOptions, OnOptions } from "solid-js";
export type { ResolvedJSXElement, ResolvedChildren } from "solid-js/types/reactive/signal.js";
/**
* Can be single or in an array
*/
export type Many<T> = T | T[];
export type Values<O extends Object> = O[keyof O];
export type Noop = (...a: any[]) => void;
export type Directive<P = true> = (el: Element, props: Accessor<P>) => void;
/**
* Infers the type of the array elements
*/
export type ItemsOf<T> = T extends (infer E)[] ? E : never;
export type ItemsOfMany<T> = T extends any[] ? ItemsOf<T> : T;
export type SetterParam<T> = Parameters<Setter<T>>[0];
/**
* T or a reactive/non-reactive function returning T
*/
export type MaybeAccessor<T> = T | Accessor<T>;
/**
* Accessed value of a MaybeAccessor
* @example
* ```ts
* MaybeAccessorValue<MaybeAccessor<string>>
* // => string
* MaybeAccessorValue<MaybeAccessor<() => string>>
* // => string | (() => string)
* MaybeAccessorValue<MaybeAccessor<string> | Function>
* // => string | void
* ```
*/
export type MaybeAccessorValue<T extends MaybeAccessor<any>> = T extends () => any ? ReturnType<T> : T;
export type OnAccessEffectFunction<S, Prev, Next extends Prev = Prev> = (input: AccessReturnTypes<S>, prevInput: AccessReturnTypes<S>, v: Prev) => Next;
export type AccessReturnTypes<S> = S extends MaybeAccessor<any>[] ? {
[I in keyof S]: AccessReturnTypes<S[I]>;
} : MaybeAccessorValue<S>;
/** Allows to make shallow overwrites to an interface */
export type Modify<T, R> = Omit<T, keyof R> & R;
/** Allows to make nested overwrites to an interface */
export type ModifyDeep<A extends AnyObject, B extends DeepPartialAny<A>> = {
[K in keyof A]: B[K] extends never ? A[K] : B[K] extends AnyObject ? ModifyDeep<A[K], B[K]> : B[K];
} & (A extends AnyObject ? Omit<B, keyof A> : A);
/** Makes each property optional and turns each leaf property into any, allowing for type overrides by narrowing any. */
export type DeepPartialAny<T> = {
[P in keyof T]?: T[P] extends AnyObject ? DeepPartialAny<T[P]> : any;
};
/** Removes the `[...list]` functionality */
export type NonIterable<T> = T & {
[Symbol.iterator]: never;
};
/** Get the required keys of an object */
export type RequiredKeys<T> = keyof {
[K in keyof T as T extends {
[_ in K]: unknown;
} ? K : never]: 0;
};
/** Remove the first item of a tuple [1, 2, 3, 4] => [2, 3, 4] */
export type Tail<T extends any[]> = ((...t: T) => void) extends (x: any, ...u: infer U) => void ? U : never;
/** `A | B => A & B` */
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
export type ExtractIfPossible<T, U> = Extract<T, U> extends never ? U : Extract<T, U>;
export type AnyObject = Record<PropertyKey, any>;
export type AnyStatic = [] | any[] | AnyObject;
export type AnyFunction = (...args: any[]) => any;
export type AnyClass = abstract new (...args: any) => any;
export type PrimitiveValue = PropertyKey | boolean | bigint | null | undefined;
export type FalsyValue = false | 0 | "" | null | undefined;
export type Truthy<T> = Exclude<T, FalsyValue>;
export type Falsy<T> = Extract<T, FalsyValue>;
export type Position = {
x: number;
y: number;
};
export type Size = {
width: number;
height: number;
};
/** Unwraps the type definition of an object, making it more readable */
export type Simplify<T> = T extends object ? {
[K in keyof T]: T[K];
} : T;
/** Unboxes type definition, making it more readable */
export type UnboxLazy<T> = T extends () => infer U ? U : T;
type RawNarrow<T> = (T extends [] ? [] : never) | (T extends string | number | bigint | boolean ? T : never) | {
[K in keyof T]: T[K] extends Function ? T[K] : RawNarrow<T[K]>;
};
export type Narrow<T> = T extends [] ? T : RawNarrow<T>;
export type NoInfer<T> = [T][T extends any ? 0 : never];