Repository: babel/babel
File: packages/babel-plugin-proposal-destructuring-private/src/util.ts (TypeScript)

Code before:
/**
 * grow `excludingKeys` from given properties. This routine mutates properties by
 * memoising the computed non-static keys.
 *
 * @param {ExcludingKey[]} excludingKeys
 * @param {t.ObjectProperty[]} properties An array of object properties that should be excluded by rest element transform
 * @param {Scope} scope Where should we register the memoised id
 */
function growRestExcludingKeys(
  excludingKeys: ExcludingKey[],
  properties: t.ObjectProperty[],
  scope: Scope,
) {
  if (excludingKeys === null) return;
  for (const property of properties) {
    const propertyKey = property.key;
    if (property.computed && !scope.isStatic(propertyKey)) {
      const tempId = scope.generateDeclaredUidIdentifier("m");
      // @ts-expect-error A computed property key must not be a private name
      property.key = assignmentExpression("=", tempId, propertyKey);
      excludingKeys.push({ key: tempId, computed: true });
    } else if (propertyKey.type !== "PrivateName") {
      const isDuplicate = excludingKeys.some(existing => {
        if (existing.computed || property.computed) return false;

        // Helper function to get the string representation of a key
        const getKeyString = (key: t.ObjectProperty["key"]): string | null => {
          switch (key.type) {
            case "Identifier":
              return key.name;
            case "StringLiteral":
              return key.value;
            case "NumericLiteral":
              return String(key.value);
            case "BigIntLiteral":
              // In Babel 8, value is bigint; in Babel 7, it's string
              return String(key.value);
            default:
              return null;
          }
        };

        const existingKeyStr = getKeyString(existing.key);
        const propertyKeyStr = getKeyString(propertyKey);

        if (existingKeyStr !== null && propertyKeyStr !== null) {
          return existingKeyStr === propertyKeyStr;
        }

        return false;
      });

Review comment (refactor):
```suggestion
        // Helper function to get the string representation of a key
        // https://tc39.es/ecma262/#prod-LiteralPropertyName
```

Code after:
/**
 * grow `excludingKeys` from given properties. This routine mutates properties by
 * memoising the computed non-static keys.
 *
 * @param {ExcludingKey[]} excludingKeys
 * @param {t.ObjectProperty[]} properties An array of object properties that should be excluded by rest element transform
 * @param {Scope} scope Where should we register the memoised id
 */
function growRestExcludingKeys(
  excludingKeys: ExcludingKey[],
  properties: t.ObjectProperty[],
  scope: Scope,
) {
  if (excludingKeys === null) return;
  for (const property of properties) {
    const propertyKey = property.key;
    if (property.computed && !scope.isStatic(propertyKey)) {
      const tempId = scope.generateDeclaredUidIdentifier("m");
      // @ts-expect-error A computed property key must not be a private name
      property.key = assignmentExpression("=", tempId, propertyKey);
      excludingKeys.push({ key: tempId, computed: true });
    } else if (propertyKey.type !== "PrivateName") {
      const isDuplicate = excludingKeys.some(existing => {
        if (existing.computed || property.computed) return false;

        // Helper function to get the string representation of a key
        // Handles LiteralPropertyName (IdentifierName | StringLiteral | NumericLiteral)
        // https://tc39.es/ecma262/#prod-LiteralPropertyName
        // Also handles BigIntLiteral from computed property names
        const getKeyString = (key: t.ObjectProperty["key"]): string | null => {
          switch (key.type) {
            case "Identifier":
              return key.name;
            case "StringLiteral":
              return key.value;
            case "NumericLiteral":
              return String(key.value);
            case "BigIntLiteral":
              // In Babel 8, value is bigint; in Babel 7, it's string
              return String(key.value);
            default:
              return null;
          }
        };

        const existingKeyStr = getKeyString(existing.key);
        const propertyKeyStr = getKeyString(propertyKey);

        if (existingKeyStr !== null && propertyKeyStr !== null) {
          return existingKeyStr === propertyKeyStr;
        }