[jasmine] Allow calling spyOn for class constructors and add AnyMethods type to jasmine namespace (#35483)

* Add AnyMethods to jasmine namespace

* ts-bot only checks top level index.d.ts files
This commit is contained in:
Moshe Kolodny 2019-05-28 16:54:21 -04:00 committed by Sheetal Nandi
parent 5ce88a3373
commit 77f45609e6
3 changed files with 33 additions and 8 deletions

View File

@ -11,6 +11,7 @@
// Yaroslav Admin <https://github.com/devoto13>
// Domas Trijonis <https://github.com/fdim>
// Peter Safranek <https://github.com/pe8ter>
// Moshe Kolodny <https://github.com/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

View File

@ -150,20 +150,18 @@ interface DoneFn extends Function {
fail: (message?: Error | string) => void;
}
type Methods<T> = {
[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<T, K extends keyof T = keyof T>(
object: T, method: T[K] extends InferableFunction ? K : never,
): jasmine.Spy<T[K] extends InferableFunction ? T[K] : never>;
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<string> | {[methodName: string]: any}) :
(ReadonlyArray<keyof T> | {[P in keyof T]?: ReturnType<T[P] extends InferableFunction ? T[P] : any>});
type AnyMethods<T> = {
[K in {
[K in keyof T]: T[K] extends Function ? K : never
}[keyof T]]: InferableFunction
};
function clock(): Clock;
var matchersUtil: MatchersUtil;

View File

@ -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<jasmine.AnyMethods<I>>("spyObject", ["f"]);
spyObject.f.and.returnValue("a string - working");
});
});
});