Extending with generics

Topics: General
Sep 16, 2013 at 11:16 AM
Edited Sep 16, 2013 at 11:45 AM
I'm playing around with the Jasmine definition file trying to get the 'createSpy' method to return something more strongly typed to the class it is mocking.
// Current prototype
function createSpy(name: string, originalFn?: Function): Spy;

// Strongly typed prototype
function createSpy<T>(name: string, originalFn?: T): TypedSpy<T>; 
Here's my attempt at creating a strongly typed 'Spy' interface:
interface TypedSpy<T> extends T, Spy {} 
// error TS2075: An interface may only extend another class or interface.
Is there any way to make this work?

Alternatively is there some way for me to define the return type as 'T extended with Spy'?
Sep 16, 2013 at 12:17 PM
Edited Sep 16, 2013 at 12:21 PM
Fixed this issue once I realised I needed to be using 'jasmine.createSpyObj' and updated the definition file to be:
function createSpyObj<T>(baseName: string, methodNames: any[]): T;
However it has left me wondering how I'd specify the return type of a function extending an object with Underscore.js:
function ExtendObject<T>(object: T): ??? {
  return _(object).extend(objectToExtendWith);
Sep 17, 2013 at 1:15 AM
Perhaps this does what you want?
function ExtendObject<T, U extends T>(object: T): U {
    return _(object).extend(objectToExtendWith);
Sep 17, 2013 at 9:54 AM
Edited Sep 17, 2013 at 10:13 AM
Thanks Dan.

That would work but (unless I'm misunderstanding) it has the limitation that you'd have to specify an interface explicitly that defined U?
function ExtendObject<T>(object1: T, object2: Class2): U extends T, Class2 {
    return _(object1).extend(object2);

var extendedObj = ExtendObject<Class1>(object1, object2);
Ideally I'd like to be able to do something like the above leaving extendedObj with the methods / properties of both Class1 and Class2. There's probably some pitfalls to this that prevent this kind of dynamic typing but it would be very useful to do without having to explicitly define an interface (especially when dealing with unit testing and mocks).