Russell Seamer
Russell Seamer

Reputation: 146

TypeScript generics - type inference

I'm trying to recreate something in TypeScript that works in C#. In the code below, I was expecting both response1 and response2 to be a Promise<number>, but response1 doesn't seem to infer the generic type correctly.

Is this possible? Or is it just something that TypeScript cannot do?

interface IRequest<TResponse> {}

interface MyRequest extends IRequest<number> {
    id: string;
}

function execute<TResponse>(request: IRequest<TResponse>): Promise<TResponse>{
    return Promise.reject("not implemented");
}

// const response1: Promise<{}>
const response1 = execute(<MyRequest>{
    id: "123"
});

// const response2: Promise<number>
const response2 = execute(<IRequest<number>>{
    id: "123"
});

Upvotes: 2

Views: 248

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250266

Typescript uses structural compatibility for type compatibility, so things like the inheritance list of an interface are not as important, what matters is the structure of the type. In your case the IRequest interface does not use the TResponse type argument at all, so it's actually structurally equivalent to {}, so it will matter little that MyRequest extends this interface. If IRequest were to use the type parameter, inference will work as expected:

interface IRequest<TResponse> {
  _response?: TResponse
}

interface MyRequest extends IRequest<number> {
    id: string;
}

function execute<TResponse>(request: IRequest<TResponse>): Promise<TResponse>{
    return Promise.reject("not implemented");
}

// const response1: Promise<number>
const response1 = execute(<MyRequest>{
    id: "123"
});

// const response2: Promise<number>
const response2 = execute(<IRequest<number>>{
    id: "123"
});

Playground link

Upvotes: 5

Related Questions