diff --git a/src/utils/typescript/typescript-member.ts b/src/utils/typescript/typescript-member.ts new file mode 100644 index 0000000..d6300ca --- /dev/null +++ b/src/utils/typescript/typescript-member.ts @@ -0,0 +1,41 @@ +import { TypeScriptNode } from "./typescript-node"; +import { DEFAULT_QUOTES } from "./typescript-formatting-options"; + +/** + * Represents a member in a TypeScript object. + */ +export interface TypeScriptMember extends TypeScriptNode { + /** + * Gets the name of the member. + */ + get name(): string; +} + +/** + * Determines whether a name is a valid TypeScript member name. + * + * @param name - The name to check. + * + * @returns `true` if the name is a valid TypeScript member name; otherwise, `false`. + */ +export function isValidMemberName(name: string): boolean { + return /^[\p{L}_][\p{L}0-9_]*$/u.test(name); +} + +/** + * Escapes a member name so that it can be used safely in TypeScript code. + * + * @param name - The name of the member to escape. + * @param quotes - Quotes to use around the escaped name. Defaults to {@link DEFAULT_QUOTES}. + * + * @returns The escaped member name. + */ +export function escapeMemberName(name: string, quotes?: string): string { + if (isValidMemberName(name)) { + return name; + } + + quotes ||= DEFAULT_QUOTES; + const escapedName = JSON.stringify(name).slice(1, -1).replaceAll(/[`']/g, "\\$&"); + return `[${quotes}${escapedName}${quotes}]`; +}