Repository: angular/angular
File: devtools/projects/ng-devtools-backend/src/lib/router-tree.ts (TypeScript)

Code before:

    if (child.data) {
      for (const el in child.data) {
        if (child.data.hasOwnProperty(el)) {
          routeConfig?.data?.push({
            key: el,
            value: child.data[el],
          });
        }
      }
    }

    return routeConfig;
  });
}

/**
 * Get the display name for a function or class.
 * @param fn - The function or class to get the name from
 * @param defaultName - Optional name to check against. If the function name matches this value,
 * '[Function]' is returned instead
 * @returns The formatted name: class name, function name with '()', or '[Function]' for anonymous/arrow functions
 */
function getClassOrFunctionName(fn: Function, defaultName?: string) {
  const isArrow = !fn.hasOwnProperty('prototype');
  if (isArrow) {
    return '[Function]';
  }

  const hasDefaultName = fn.name === defaultName;
  if (hasDefaultName) {
    return '[Function]';
  }

  // Check if it's a class by examining the function's string representation
  const isClass = /^class\s/.test(fn.toString());

  // Return class name without parentheses, function name with parentheses
  return isClass ? fn.name : `${fn.name}()`;
}

function getPropertyName(child: AngularRoute, property: 'title' | 'redirectTo') {
  if (child[property] instanceof Function) {
    return getClassOrFunctionName(child[property], property);
  }

  return child[property];
}

function childRouteName(child: AngularRoute): string {
  if (child.component) {

Review comment (suggestion):
nit: Is there a reason why this ignores names of arrow functions?

For context, `fn.name` of the following should be `myFn`:

```ts
const myFn = () => {};
```

Code after:

    if (child.data) {
      for (const el in child.data) {
        if (child.data.hasOwnProperty(el)) {
          routeConfig?.data?.push({
            key: el,
            value: child.data[el],
          });
        }
      }
    }

    return routeConfig;
  });
}

/**
 * Get the display name for a function or class.
 * @param fn - The function or class to get the name from
 * @param defaultName - Optional name to check against. If the function name matches this value,
 * '[Function]' is returned instead
 * @returns The formatted name: class name, function name with '()', or '[Function]' for anonymous/arrow functions
 */
function getClassOrFunctionName(fn: Function, defaultName?: string) {
  const isArrowWithNoName = !fn.hasOwnProperty('prototype') && fn.name === '';

  if (isArrowWithNoName) {
    return '[Function]';
  }

  const hasDefaultName = fn.name === defaultName;
  if (hasDefaultName) {
    return '[Function]';
  }

  // Check if it's a class by examining the function's string representation
  const isClass = /^class\s/.test(fn.toString());

  // Return class name without parentheses, function name with parentheses
  return isClass ? fn.name : `${fn.name}()`;
}

function getPropertyName(child: AngularRoute, property: 'title' | 'redirectTo') {
  if (child[property] instanceof Function) {
    return getClassOrFunctionName(child[property], property);
  }

  return child[property];
}

function childRouteName(child: AngularRoute): string {