From 9b912e2e564a06a6b3e51029f03eb8f46b75fef6 Mon Sep 17 00:00:00 2001
From: Kir_Antipov <kp.antipov@gmail.com>
Date: Mon, 6 Feb 2023 07:37:08 +0000
Subject: [PATCH] Made interface that represents a TypeScript member

---
 src/utils/typescript/typescript-member.ts | 41 +++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 src/utils/typescript/typescript-member.ts

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}]`;
+}