diff --git a/types/jasmine/index.d.ts b/types/jasmine/index.d.ts index c1cfcdc913..3746abacf0 100644 --- a/types/jasmine/index.d.ts +++ b/types/jasmine/index.d.ts @@ -11,6 +11,7 @@ // Yaroslav Admin // Domas Trijonis // Peter Safranek +// Moshe Kolodny // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 // For ddescribe / iit use : https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/karma-jasmine/karma-jasmine.d.ts diff --git a/types/jasmine/ts3.1/index.d.ts b/types/jasmine/ts3.1/index.d.ts index c5c39b342c..21bb6b5440 100644 --- a/types/jasmine/ts3.1/index.d.ts +++ b/types/jasmine/ts3.1/index.d.ts @@ -150,20 +150,18 @@ interface DoneFn extends Function { fail: (message?: Error | string) => void; } -type Methods = { - [K in { - [K in keyof T]: T[K] extends Function ? K : never - }[keyof T]]: T[K] -}; - /** * Install a spy onto an existing object. * @param object The object upon which to install the `Spy`. * @param method The name of the method to replace with a `Spy`. */ declare function spyOn( - object: T, method: T[K] extends InferableFunction ? K : never, -): jasmine.Spy; + object: T, method: T[K] extends Function ? K : never, +): jasmine.Spy< + T[K] extends InferableFunction ? T[K] : + T[K] extends {new (...args: infer A): infer V} ? (...args: A) => V : + T[K] extends Function ? InferableFunction : never +>; /** * Install a spy on a property installed with `Object.defineProperty` onto an existing object. @@ -190,6 +188,12 @@ declare namespace jasmine { (ReadonlyArray | {[methodName: string]: any}) : (ReadonlyArray | {[P in keyof T]?: ReturnType}); + type AnyMethods = { + [K in { + [K in keyof T]: T[K] extends Function ? K : never + }[keyof T]]: InferableFunction + }; + function clock(): Clock; var matchersUtil: MatchersUtil; diff --git a/types/jasmine/ts3.1/jasmine-tests.ts b/types/jasmine/ts3.1/jasmine-tests.ts index 92c2a87494..5bea796b2d 100644 --- a/types/jasmine/ts3.1/jasmine-tests.ts +++ b/types/jasmine/ts3.1/jasmine-tests.ts @@ -1194,6 +1194,16 @@ describe('better typed spys', () => { // $ExpectType string spy.calls.first().returnValue; }); + it('works on constructors', () => { + class MyClass { + constructor(readonly foo: string) {} + } + const namespace = { MyClass }; + const spy = spyOn(namespace, 'MyClass'); + spy.and.returnValue({foo: 'test'}); + spy.and.returnValue({}); // $ExpectError + spy.and.returnValue({foo: 123}); // $ExpectError + }); it('can allows overriding the generic', () => { class Base { service() {} @@ -1218,6 +1228,16 @@ describe('better typed spys', () => { // $ExpectType (val: string) => Spy<() => string> spyObj.method.and.returnValue; }); + + it('has a way to opt out of inferred function types', () => { + interface I { + f(): string; + f(x: any): number; + } + + const spyObject = jasmine.createSpyObj>("spyObject", ["f"]); + spyObject.f.and.returnValue("a string - working"); + }); }); });