Why TypeScript Infers 'unknown' for Your Function Return Value (And How to Fix It)
Understanding the "Type 'unknown' is not assignable" Error in TypeScript Generics
It is a common point of confusion when working with TypeScript: you explicitly declare the return type of your outer function, yet TypeScript still complains that the returned value is unknown inside the function body. Why doesn't TypeScript just look at your function's return signature and infer the type from there?
Let's dive into why this happens and how to solve it cleanly without resorting to unsafe type assertions (like as TeamType[]).
The Root Cause: Missing Generic Type Arguments
The issue lies in how your httpRequest wrapper is defined and called. Let's look at its signature:
export async function httpRequest<T>(
url: string,
method: string,
body?: BodyInit,
): Promise<T>This is a generic function. It expects a type placeholder T. However, notice that T is only used in the return type (Promise<T>), not in any of the function's arguments (like url or method).
When you call the function like this:
const response = await httpRequest("/api/cash-teams", "GET");TypeScript looks at the arguments you passed ("/api/cash-teams" and "GET") to try and infer what T should be. Since T is not associated with any of those input parameters, TypeScript has no way of automatically guessing what type you expect. Consequently, it falls back to the safest default: unknown.
Because response is inferred as unknown, you cannot return it from a function that is explicitly typed to return Promise<TeamType[]>. TypeScript prevents this because unknown is not safely assignable to TeamType[] without verification.
The Solution: Pass the Type Argument Explicitly
To fix this, you need to tell httpRequest what type of data you expect it to return by passing the type argument when you call it:
export async function fetchCashTeams(): Promise<TeamType[]> {
// Pass TeamType[] as the generic parameter T
const response = await httpRequest<TeamType[]>("/api/cash-teams", "GET");
return response; // No more errors!
}By writing httpRequest<TeamType[]>(...), you are explicitly setting T to TeamType[]. Now, response is correctly typed as TeamType[], which perfectly matches the return type of your fetchCashTeams function.
Why This is Better Than Using "as" (Type Assertion)
While writing return response as TeamType[] silences the compiler, it is generally considered an anti-pattern. Type assertions bypass TypeScript's type safety checks and tell the compiler "trust me, I know what I'm doing," which can lead to runtime bugs if the API contract changes.
By passing the generic parameter directly to httpRequest<TeamType[]>, you ensure that the entire data flow inside httpRequest—including the internal ApiResponse<T> mapping—remains strongly typed, safe, and self-documenting.