import { isSymbol } from "./is.ts" /** * @description Create a new unique symbol with an optional description. * * @example * ``` * // Expect: true * const example1 = typeof symbolCreateLocal("demo") === "symbol" * // Expect: false * const example2 = symbolCreateLocal("demo") === symbolCreateLocal("demo") * ``` */ export const symbolCreateLocal = (description?: string): symbol => { return Symbol(description) } /** * @description Get or create a global symbol for the given key. * * @example * ``` * // Expect: true * const example1 = symbolCreateGlobal("demo") === Symbol.for("demo") * // Expect: true * const example2 = symbolCreateGlobal("demo") === symbolCreateGlobal("demo") * ``` */ export const symbolCreateGlobal = (key: string): symbol => Symbol.for(key) /** * @description Get the key for a global symbol, or undefined if not global. * * @example * ``` * // Expect: "demo" * const example1 = symbolGetKey(Symbol.for("demo")) * // Expect: undefined * const example2 = symbolGetKey(Symbol("demo")) * ``` */ export const symbolGetKey = (value: unknown): string | undefined => { return isSymbol(value) ? Symbol.keyFor(value) : undefined } /** * @description Check whether a symbol is from the global registry. * * @example * ``` * // Expect: true * const example1 = symbolIsGlobal(Symbol.for("demo")) * // Expect: false * const example2 = symbolIsGlobal(Symbol("demo")) * ``` */ export const symbolIsGlobal = (value: unknown): value is symbol => { return isSymbol(value) && Symbol.keyFor(value) !== undefined } /** * @description Check whether a symbol is not from the global registry. * * @example * ``` * // Expect: false * const example1 = symbolIsLocal(Symbol.for("demo")) * // Expect: true * const example2 = symbolIsLocal(Symbol("demo")) * ``` */ export const symbolIsLocal = (value: unknown): value is symbol => { return isSymbol(value) && Symbol.keyFor(value) === undefined } /** * @description Check whether a symbol has a description. * * @example * ``` * // Expect: true * const example1 = symbolHasDescription(Symbol("demo")) * // Expect: false * const example2 = symbolHasDescription(Symbol()) * ``` */ export const symbolHasDescription = (value: unknown): value is symbol => { return isSymbol(value) && value.description !== undefined } /** * @description Get the description of a symbol, or undefined for non-symbols. * * @example * ``` * // Expect: "demo" * const example1 = symbolGetDescription(Symbol("demo")) * // Expect: undefined * const example2 = symbolGetDescription(Symbol()) * ``` */ export const symbolGetDescription = (value: unknown): string | undefined => { return isSymbol(value) ? value.description : undefined } /** * @description Check whether a symbol is anonymous (no description). * * @example * ``` * // Expect: false * const example1 = symbolIsAnonymous(Symbol("demo")) * // Expect: true * const example2 = symbolIsAnonymous(Symbol()) * ``` */ export const symbolIsAnonymous = (value: unknown): value is symbol => { return isSymbol(value) && value.description === undefined } const internalWellKnownSymbols = new Set([ Symbol.asyncIterator, Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator, Symbol.match, Symbol.matchAll, Symbol.replace, Symbol.search, Symbol.species, Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables, ]) /** * @description Check whether a symbol is one of the well-known symbols. * * @example * ``` * // Expect: true * const example1 = symbolIsWellKnown(Symbol.iterator) * // Expect: false * const example2 = symbolIsWellKnown(Symbol("iterator")) * ``` */ export const symbolIsWellKnown = (value: unknown): value is symbol => { return isSymbol(value) && internalWellKnownSymbols.has(value) } /** * @description Convert a symbol to its string representation. * * @example * ``` * // Expect: "Symbol(demo)" * const example1 = symbolToString(Symbol("demo")) * // Expect: undefined * const example2 = symbolToString("demo") * ``` */ export const symbolToString = (value: unknown): string | undefined => { return isSymbol(value) ? value.toString() : undefined }