Skip to main content

Generic without extends

1. What "generic without extends" means

When you declare a generic like this:

javascript
function identity<T>(value: T): T { return value; }

you're telling TypeScript:

"T can be absolutely any type."

And this is really true: T can be a number, a string, an object, an array, a function, null, undefined, void, never, anything.


2. What's the problem?

The problem isn't the generic itself, it's the assumptions the developer makes about type T.

Let's look at an example:

javascript
function getLength<T>(value: T): number { return value.length; // Error: T might not have length! }

TypeScript complains because T can be anything, even number or boolean, and then length doesn't exist.


Why this is unsafe

If TypeScript didn't check this, you could write code like this:

javascript
function unsafeLength<T>(value: T): number { return (value as any).length; } console.log(unsafeLength(123)); // undefined console.log(unsafeLength(true)); // undefined

The code compiles, but the behavior is unpredictable, runtime errors are guaranteed. TypeScript no longer protects you.


3. How to fix it: add extends

You can constrain the generic so it only fits certain types:

javascript
function getLength<T extends { length: number }>(value: T): number { return value.length; // safe }

Now T must be an object (or an array, a string, and so on) that is guaranteed to have a length property.

It works:

javascript
getLength("hello"); // 5 getLength([1, 2, 3]); // 3

It doesn't work:

javascript
getLength(42); // Error - number has no length

Thanks to extends, TypeScript knows which properties can be used.


4. An example of an unsafe generic without extends

javascript
function merge<T, U>(a: T, b: U): T & U { return { ...a, ...b }; } merge(1, "test"); // Logically meaningless, but TS doesn't forbid it

TypeScript doesn't know that T and U are supposed to be objects, and it allows you to pass numbers, strings, and even null.


A safe version:

javascript
function merge<T extends object, U extends object>(a: T, b: U): T & U { return { ...a, ...b }; } merge({ name: "Tim" }, { age: 25 }); // OK merge(1, "test"); // Error - not an object

Now TypeScript strictly tracks the data structure.


5. Another example: with keys

Without extends, it's easy to "break" the type logic:

javascript
function getValue<T, K>(obj: T, key: K) { return obj[key]; // Error: T might not have property K }

The correct way: constrain K:

javascript
function getValue<T, K extends keyof T>(obj: T, key: K) { return obj[key]; // safe } getValue({ name: "Tim", age: 25 }, "name"); // OK getValue({ name: "Tim" }, "invalid"); // Error - no such key

Thanks to extends keyof T, TypeScript knows that key must be an existing property of the object.


6. Why this matters

If a generic is unconstrained (T without extends):

  • you cannot safely use properties or methods of that type;
  • TypeScript doesn't know which operations are allowed;
  • there's a temptation to "plug" types with as any, which makes the code unsafe.

7. Rule of thumb

SituationWhat to do
You use a generic but don't access propertiesfunction identity<T>(x: T): T - fine
You use properties of the type (.length, .id, etc.)Add extends { length: number }
You use object keysAdd K extends keyof T
You expect the generic to be an objectAdd extends object
You want to restrict to interface implementersAdd extends MyInterface

Summary

Without extendsWith extends
T can be any typeT is constrained to a specific structure
The compiler doesn't know which properties existThe compiler checks allowed properties
Runtime errors are possibleErrors are caught at compile time
Often requires as anyRarely requires as
Less predictable codeSafe and self-documenting code

Put simply:

A generic without extends is a "universal container with no restrictions". Without restrictions, TypeScript cannot protect you.

Add extends when a generic must satisfy a specific contract (a structure, an interface, or keys).

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.