When clean API design meets deep JavaScript internals. 🚀

Backend-focused Software Engineer skilled in Node.js, Go, TypeScript, and scalable API design, dedicated to building high-performance, reliable, and efficient web systems.
We often rely on syntactic sugar in modern development, but there is immense value in understanding the raw mechanics of JavaScript—specifically how Prototypes, Context (this), and Fluent Interfaces work together.
I was experimenting with a pattern today that combines these concepts to create a readable, chainable API.
Why is this snippet interesting?
Fluent Interface (Method Chaining): By returning
thisat the end ofsayHello, we enable endless chaining:.sayHello().sayHello().multiply(). This makes the code read like a sentence, vastly improving Developer Experience (DX).Prototype vs. Own Properties (Shadowing): The code explicitly distinguishes between the instance (
Rony) and the prototype (Borhan).obj.hasOwnProperty("name")returns true because "Rony" is on the instance.However, we can still access the "parent" data via the prototype chain.
Generics & Binding: Using TypeScript generics
<T extends Class>combined with.bind, we create a strictly typed factory function that pre-fills arguments ("Khulna", "Bangladesh") while maintaining type safety.
It’s a great exercise to remember that under every fancy TypeScript class, there is a powerful (and sometimes complex) prototype chain doing the heavy lifting. 🛠️
Here is the code structure:
type Class = new () => any;
type Person = {
name: string;
sayHello: () => Person;
multiply: () => void;
};
function Person(this: Person) {
this.name = "Rony"; // Instance Property
this.sayHello = function () {
console.log(`hello ${this.name}`);
return this; // Enables Chaining
};
this.multiply = function () {
console.log("Multiplication");
};
}
// Shared Prototype Data
Person.prototype = {
name: "Borhan",
};
const obj = {
test<T extends Class, U extends any[]>(this: T, country: U) {
const obj = new this() as Object;
// Proving "Rony" is an Own Property
console.log("TCL: obj.hasOwnProperty()", obj.hasOwnProperty("name"));
// Accessing the Prototype (Borhan)
const prototype = Object.getPrototypeOf(obj);
console.log(`${prototype.name} is from ${country[0]},${country[1]}`);
return obj as () => T;
},
};
const getInfo = obj.test.bind(Person, ["Khulna", "Bangladesh"]);
// The Result: A clean, fluent API
getInfo()
.sayHello()
.sayHello()
.multiply();
