Reputation: 23284
The Tester.test()
method will compile and run successfully even though SomeQuery1
implements IQueryWithResponse<SomeResponse1>
and not iQueryWithResponse<SomeResponse2>
export interface IQueryWithResponse<TResponse> {
}
export class SomeQuery1 implements IQueryWithResponse<SomeResponse1> {
}
export class SomeResponse1 {
}
export class SomeQuery2 implements IQueryWithResponse<SomeResponse2> {
}
export class SomeResponse2 {
}
export class Tester {
public doRequest<TRequest extends IQueryWithResponse<TResponse>, TResponse>(request: TRequest) : TResponse {
return null;
}
public test() {
let query = new SomeQuery1();
let response = this.doRequest<SomeQuery1, SomeResponse2>(query);
}
}
If this were a language like C# the compiler would throw an error due to the constraint on Tester.doRequest()
, but in TypeScript I can pass any type for TResponse
as long as it implements the same members as the type I am expecting (which in this example is absolutely anything).
I would like to be able to enforce this generic constraint checking at compile time. Or, at the very least, have a way of ensuring in Tester.doRequest
at runtime that request
implements IQueryWithResponse<TResponse>
Perhaps there is a way to solve this using meta-data?
Upvotes: 0
Views: 179
Reputation: 26448
Only way I know of is to have some constant value that differentiates the interfaces. Its technically the same "type" (string) but typescript allows you to be specific about its expected value(s) and will complain if the constant doesn't match.
Its a solution; can't say I like it. :P
Upvotes: 1