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

Code before:
          existing.key.type === "Identifier" &&
          propertyKey.type === "Identifier"
        ) {
          return existing.key.name === propertyKey.name;
        }
        return false;
      });
      if (!isDuplicate) {
        excludingKeys.push(property);
      }
    }
  }
}

/**
 * Prepare var declarations for params. Only param initializers
 * will be transformed to undefined coalescing, other features are preserved.
 * This function does NOT mutate given AST structures.
 *
 * @export
 * @param {Function["params"]} params An array of function params
 * @param {Scope} scope A scope used to generate uid for function params
 * @returns {{ params: Identifier[]; variableDeclaration: VariableDeclaration }} An array of new id for params
 * and variable declaration to be prepended to the function body
 */
export function buildVariableDeclarationFromParams(
  params: t.Function["params"],
  scope: Scope,
): {
  params: (t.Identifier | t.RestElement)[];
  variableDeclaration: t.VariableDeclaration;
} {
  const { elements, transformed } = buildAssignmentsFromPatternList(
    params,
    scope,
    /* isAssignment */ false,
  );
  return {
    params: elements,
    variableDeclaration: variableDeclaration(
      "var",
      transformed.map(({ left, right }) =>
        variableDeclarator(
          left as t.Identifier | t.ArrayPattern | t.ObjectPattern,
          right,
        ),
      ),
    ),
  };
}


Review comment (performance):
Nit: A literal property name can also be one of 
- string literal (`"0"`)
- numerical literal (`0`)
- bigint literal (`0n`)

To optimize the output, we should also check these AST types for potential duplicates. 

Code after:
        // 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;
        }

        return false;
      });
      if (!isDuplicate) {
        excludingKeys.push(property);
      }
    }
  }
}

/**
 * Prepare var declarations for params. Only param initializers
 * will be transformed to undefined coalescing, other features are preserved.
 * This function does NOT mutate given AST structures.
 *
 * @export
 * @param {Function["params"]} params An array of function params
 * @param {Scope} scope A scope used to generate uid for function params
 * @returns {{ params: Identifier[]; variableDeclaration: VariableDeclaration }} An array of new id for params
 * and variable declaration to be prepended to the function body
 */
export function buildVariableDeclarationFromParams(
  params: t.Function["params"],
  scope: Scope,
): {