@etsoo/shared
Version:
TypeScript shared utilities and functions
479 lines (478 loc) • 13.4 kB
TypeScript
/**
* Generic object type
* Narrow case, uses StringRecord
* Before was wrong with {}, from 4.8 unknown = {} | null | undefined
*/
declare global {
interface BigInt {
toJSON(): String;
}
}
/**
* Interface data types
*/
export declare namespace DataTypes {
/**
* Basic types, includes number, bigint, Date, boolean, string
*/
type Basic = number | bigint | Date | boolean | string;
/**
* Basic type and basic type array names array
*/
const BasicArray: readonly ["number", "number[]", "bigint", "bigint[]", "date", "date[]", "boolean", "boolean[]", "string", "string[]", "unknown[]"];
/**
* Basic type names
*/
type BasicNames = (typeof BasicArray)[number];
/**
* Basic type template
*/
type BasicTemplate = {
[key: string]: BasicNames;
};
/**
* Basic template type
*/
type BasicTemplateType<T extends BasicTemplate> = {
[P in keyof T]?: BasicConditional<T[P]>;
};
/**
* Basic conditinal type
*/
type BasicConditional<T extends BasicNames> = T extends "string" ? string : T extends "string[]" ? string[] : T extends "date" ? Date : T extends "date[]" ? Date[] : T extends "boolean" ? boolean : T extends "boolean[]" ? boolean[] : T extends "number" ? number : T extends "number[]" ? number[] : T extends "bigint" ? bigint : T extends "bigint[]" ? bigint[] : unknown[];
/**
* Basic or basic array type
*/
type Simple = Basic | Array<Basic>;
/**
* Simple type enum
*/
enum SimpleEnum {
Number = 1,
Bigint = 2,
Date = 3,
Boolean = 4,
String = 5,
Array = 9
}
/**
* Simple type names
*/
type SimpleNames = Lowercase<keyof typeof SimpleEnum>;
/**
* Extended type enum
*/
enum ExtendedEnum {
Unkwown = 0,
Int = 10,
Money = 11,
IntMoney = 12,
DateTime = 13,
Email = 21,
Phone = 22,
URL = 23,
Logo = 24
}
/**
* Combined type enum
*/
const CombinedEnum: {
[x: number]: string;
Unkwown: ExtendedEnum.Unkwown;
Int: ExtendedEnum.Int;
Money: ExtendedEnum.Money;
IntMoney: ExtendedEnum.IntMoney;
DateTime: ExtendedEnum.DateTime;
Email: ExtendedEnum.Email;
Phone: ExtendedEnum.Phone;
URL: ExtendedEnum.URL;
Logo: ExtendedEnum.Logo;
Number: SimpleEnum.Number;
Bigint: SimpleEnum.Bigint;
Date: SimpleEnum.Date;
Boolean: SimpleEnum.Boolean;
String: SimpleEnum.String;
Array: SimpleEnum.Array;
};
type CombinedEnum = SimpleEnum | ExtendedEnum;
/**
* Horizontal align enum
*/
enum HAlignEnum {
Left = 1,
Center = 2,
Right = 3
}
/**
* Horizontal align
*/
type HAlign = Lowercase<keyof typeof HAlignEnum>;
/**
* Vertical align enum
*/
enum VAlignEnum {
Top = 1,
Center = 2,
Bottom = 3
}
/**
* Vertical align
*/
type VAlign = Lowercase<keyof typeof VAlignEnum>;
/**
* Placement enum
*/
enum PlacementEnum {
TopLeft = 0,
TopCenter = 1,
TopRight = 2,
MiddleLeft = 3,
Center = 4,
MiddleRight = 5,
BottomLeft = 6,
BottomCenter = 7,
BottomRight = 8,
Unknown = 9
}
/**
* Placement type
*/
type Placement = keyof typeof PlacementEnum;
/**
* Edit type from adding type
*/
type EditType<T, I extends IdType = number> = Partial<T> & {
id: I;
changedFields?: (keyof T & string)[];
};
/**
* Key collection, like { key1: {}, key2: {} }
*/
type KeyCollection<K extends readonly string[], I extends object> = {
[P in K[number]]: I;
};
/**
* Enum value type
*/
type EnumValue = number | string;
/**
* Enum base type
*/
type EnumBase = Record<string, EnumValue>;
/**
* Function type
*/
type Func<R> = (...args: any[]) => R;
/**
* Mixins constructor
*/
type MConstructor<T = {}> = new (...args: any[]) => T;
/**
* Make properties optional
*/
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
/**
* String key, unknown value Record
*/
type StringRecord = Record<string, unknown>;
/**
* String key, string value Record
*/
type StringDictionary = Record<string, string>;
/**
* Simple object, string key, simple type and null value Record
*/
type SimpleObject = Record<string, Simple | null | undefined>;
/**
* Item with id property
*/
type IdItem<T extends IdType = number> = {
/**
* Id field
*/
id: T;
};
/**
* Item with id and label property
*/
type IdLabelItem<T extends IdType = number> = IdItem<T> & {
/**
* label field
*/
label: string;
};
/**
* Item with id and name property
*/
type IdNameItem<T extends IdType = number> = IdItem<T> & {
/**
* name field
*/
name: string;
};
/**
* Item with id and title property
*/
type IdTitleItem<T extends IdType = number> = IdItem<T> & {
/**
* title field
*/
title: string;
};
/**
* Item with id and label dynamic type
*/
type IdLabelType<I extends string, L extends string, D extends IdType = number> = DIS<I, D> & DIS<L, string>;
/**
* Get specific type keys
*/
type Keys<T extends object, R = IdType> = {
[k in keyof T]: T[k] extends R ? k : never;
}[keyof T];
/**
* Require at least one property of the keys
*/
type RequireAtLeastOne<T, Keys extends keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
}[Keys];
/**
* Culture definiton
*/
type CultureDefinition<T extends StringRecord = StringRecord> = {
/**
* Name, like zh-CN
*/
readonly name: string;
/**
* Label for description, like Simplifined Chinese
*/
label: string;
/**
* Resources
*/
resources: T | (() => Promise<T>);
/**
* Compatible names
*/
readonly compatibleNames?: string[];
};
/**
* Dynamic interface with multiple properties
*/
type DI<K extends readonly string[], T> = {
[P in K[number]]: T;
};
/**
* Dynamic interface with single property
*/
type DIS<K extends string, T> = {
[P in K]: T;
};
/**
* Tristate enum
* 三态枚举
*/
enum TristateEnum {
/**
* False
* 假
*/
False = 0,
/**
* True
* 真
*/
True = 1,
/**
* Unsure
* 无法判断
*/
Unsure = 9
}
/**
* Convert value to target type
* @param input Input value
* @param target Target type
* @returns Converted value
*/
function convert<T>(input: unknown, target: T): T | undefined;
/**
* Convert by type name like 'string'
* @param input Input value
* @param targetType Target type
* @returns Converted value
*/
function convertByType<T extends BasicNames>(input: unknown, targetType: T): BasicConditional<T> | undefined;
/**
* Convert value to target enum type
* @param input Input value
* @param enumType Target enum type
* @returns Converted type
*/
function convertSimple(input: unknown, enumType: CombinedEnum): Simple | unknown[] | undefined;
/**
* Get basic type name from Enum type
* @param enumType Enum type
* @returns Basic type name result
*/
function getBasicName(enumType: CombinedEnum): BasicNames;
/**
* Get value's basic type name
* @param value Input value
* @param isArray Is array
* @returns Value's basic type name
*/
function getBasicNameByValue(value: unknown, isArray?: boolean): BasicNames | undefined;
/**
* Get enum item from key
* getEnumByKey(Gender, "Male") === Gender.Male
* @param enumItem Enum
* @param key Key
* @returns Enum item
*/
function getEnumByKey<T extends EnumBase, K extends keyof T>(enumItem: T, key: string): T[K] | undefined;
/**
* Get enum item from value
* getEnumByKey(Gender, "M") === Gender.Male
* @param enumItem Enum
* @param value Key
* @returns Enum item or undefined
*/
function getEnumByValue<T extends EnumBase, K extends keyof T>(enumItem: T, value: EnumValue): T[K] | undefined;
/**
* Get enum string literal type value
* getEnumKey(Gender, "F") === "Female"
* @param enumItem Enum item
* @param value Value
* @returns Result
*/
function getEnumKey<T extends EnumBase>(enumItem: T, value: EnumValue): string | undefined;
/**
* Get Enum keys
* @param input Input Enum
* @returns Keys
*/
function getEnumKeys<T extends EnumBase, K extends keyof T & string>(input: T): K[];
/**
* Get ListType2 item label
* @param item Item
* @returns Result
*/
function getListItemLabel<D extends ListType2>(item: D): string;
/**
* Get object item label
* @param item Item
* @returns Result
*/
function getObjectItemLabel(item: object): string;
/**
* Get object field value
* @param data Data
* @param key Property name
* @returns Value
*/
function getValue<T extends object, K extends keyof T | string>(data: T | undefined | null, key: K): K extends keyof T ? T[K] : undefined;
/**
* Get object id field value
* @param data Data
* @param key Property name
* @returns Id value
*/
function getIdValue<T extends object, K extends Keys<T, IdType>>(data: T, key: K): T[K];
/**
* Get object id field value 1
* @param data Data
* @param key Property name
* @returns Id value
*/
function getIdValue1<T extends object, K extends keyof T | string>(data: T | undefined | null, key: K): K extends keyof T ? (T[K] extends number ? number : string) : undefined;
/**
* Get object string field value
* @param data Data
* @param key Property name
* @returns String value
*/
function getStringValue<T extends object>(data: T | undefined | null, key: keyof T | string): string | undefined;
/**
* Check the type is a basic type or not (type guard)
* @param name Type name
* @returns Is basic type
*/
function isBasicName(name: string): name is BasicNames;
/**
* Is the target a simple object (Type guard)
* @param input Test data
* @param includeArray Include array as simple type
* @returns Result
*/
function isSimpleObject(input: unknown, includeArray?: boolean): input is SimpleObject;
/**
* Is the input value simple type, include null and undefined
* @param input Input value
* @param includeArray Is array included, first non null element shoud also be basic type
*/
function isSimpleType(input: unknown, includeArray?: boolean): boolean;
/**
* JSON.stringify replacer with full path
* https://stackoverflow.com/questions/61681176/json-stringify-replacer-how-to-get-full-path
*/
function jsonReplacer(replacer: (this: any, key: string, value: any, path: string) => any): (this: any, key: any, value: any) => any;
/**
* JSON.stringify receiver for bigint
* @param args Keys or paths to convert to bigint
* @returns JSON receiver function
*/
function jsonBigintReceiver(...args: string[]): (this: any, key: any, value: any) => any;
/**
* JSON serialize with options
* @param obj Object to serialize
* @param options Options to ignore null or empty values
* @returns Result
*/
function jsonSerialize(obj: unknown, options?: {
ignoreNull?: boolean;
ignoreEmpty?: boolean;
}): string;
}
/**
* Number and string combination id type
*/
export type IdType = number | string;
/**
* List item with number id type
*/
export type ListType = DataTypes.IdLabelItem<number>;
/**
* List item with string id type
*/
export type ListType1 = DataTypes.IdLabelItem<string>;
/**
* List item with compatible id and name / label / title
*/
export type ListType2 = {
id: IdType;
} & ({
label: string;
} | {
name: string;
} | {
title: string;
});
/**
* Id default type
*/
export type IdDefaultType<T extends object, I extends IdType = IdType> = T extends {
id: I;
} ? DataTypes.Keys<T, I> & "id" : DataTypes.Keys<T, I>;
/**
* Label default type
*/
export type LabelDefaultType<T extends object> = T extends {
label: string;
} ? DataTypes.Keys<T, string> & "label" : DataTypes.Keys<T, string>;
/**
* Title default type
*/
export type TitleDefaultType<T extends object> = T extends {
title: string;
} ? DataTypes.Keys<T, string> & "title" : DataTypes.Keys<T, string>;