export type IsSubType = C extends P ? true : false; export type IsEqual = [T1] extends [T2] ? ([T2] extends [T1] ? true : false) : false; export type Expect = T; export type Debug = { [K in keyof T]: T[K] }; export type IndexedType = { [key: string]: T }; // in fact, it is not PlainObject export type PlainObject = { [key: string]: V }; export type NestedPlainObject = { [key in keyof object]: T[key] extends object ? NestedPlainObject : T[key]; }; export type Activable = { active: boolean }; export type Key = string | number; // export type GetValue = T extends { [key: Key]: infer V } ? V : unknown; export type PartialBy = Omit & Partial>; // export type Tuplable = export type TupleToUnion = T[number]; export type Join = A extends string | number ? B extends string | number ? `${A}${"" extends B ? "" : "."}${B}` : never : never; // type DotPrefix = T extends '' ? '' : `.${T}`; export type ArrayIndex = "__ARRAY_INDEX__"; export const arrayIndex = "__ARRAY_INDEX__"; export type RemoveLastX = T extends `${infer P1}${X}` ? `${P1}` : T; type InnerPath = T extends Array ? { [K in Exclude]: `${ArrayIndex}.${InnerPath}`; }[Exclude] : T extends object ? { [K in Exclude]: `${K}.${InnerPath}`; }[Exclude] : ""; export type Path = RemoveLastX, ".">; export type Includes = T extends [infer F, ...infer rest] ? IsEqual extends true ? true : Includes : false; export type EmptyObject = Record; /** * @example * type A = 'a' | 'b' | 'c' | AnyString */ export type AnyString = string & Record; /** * @example * type A = 1 | 2 | 3 | AnyNumber */ export type AnyNumber = number & Record;