Listening to Syntax’s latest potluck episode in the morning reminded me how often developers write to impress rather than to express. There seems to be a holy war against TypeScript. For instance, type definitions quickly tend to become a convoluted mess in a sufficiently large codebase if not done right. Have a look at this piece of code that uses complex types and generics (picked up from this Reddit thread):
type ColTypes = { string: string; link: { text: string; href: string; }; }; type TypeFromCols< Cols extends readonly { key: string; label: string; type: "string" | "link" }[] > = { [K in Cols[number]["key"]]: ColTypes[Extract< Cols[number], { key: K } >["type"]]; }; type Narrow<T> = | (T extends infer U ? U : never) | Extract< T, number | string | boolean | bigint | symbol | null | undefined | [] > | ([T] extends [[]] ? [] : { [K in keyof T]: Narrow<T[K]> });
What started with a simple type ColTypes
evolved into something much more complex down below. To a developer new to TS, it’s an entirely alien language. But it’s not supposed to be.
I like how Scott Tolinski referred to TS as a fancy linter for JavaScript. That’s its biggest benefit. Contriving hard to appease some TS overlords or to show off our wizardry is not the goal here. The biggest, most beautiful goal is to write code other human beings can understand and be thankful to you for.
And this is true for any language in general. Writing code optimized for humans may come at the cost of performance, but wisdom has it that maintainable code turns out much more robust than convoluted or stylish code that only a few can understand.
Side note: That’s also why coding interviews should focus less on spinning out the most optimum algorithms and data structures and more on the practical aspects of a software engineer’s duties (which goes way beyond coding).