« All posts

A TypeScript Proxy Trick for React displayName Without Strings

How a C#-inspired TypeScript Proxy trick derives React component displayName values from real property access instead of fragile hardcoded strings.

A React component library wanted every component to carry a proper displayName, so the obvious approach was Component.displayName = "Component". The problem surfaced when components got renamed: the hardcoded string stayed behind, silently breaking DevTools output and log messages because string literals don't participate in IDE refactoring. A keyof-based helper improved type safety but still required string literals, couldn't express nested paths, and excluded private class members since keyof only reflects a type's public shape.

Inspired by C# expression trees, the author built a JavaScript Proxy-based technique instead. A fake target object records every property accessed on it and keeps returning itself, allowing selectors like user => user.profile.avatar.url to be walked and captured as a real path array — no AST parsing, decorators, or compiler plugins required. A thin wrapper, runtimeNameOf, extracts just the final segment, which is exactly what displayName needs.

Crucially, this doesn't bypass TypeScript's access rules: a selector can only reach a private class member from a location where that access would normally be legal, such as inside the class itself. For the displayName case, typeof import(".") supplies the module's type shape, so Component.displayName can be derived from an actual property-access expression that IDE rename tools can track. The one caveat: the proxy only understands plain property access — calling a method on it, like user.getProfile(), breaks the illusion since the proxy doesn't emulate real object behavior.