@types/xxxx package and had problems.Definitions by: in index.d.ts) so they can respond.I have a freshly updated Angular project with the latest TypeScript 3.5.2 and jasmine 3.3.13. During testing, I got an error with one of my mock objects.
export class AuthServiceMock {
constructor() {
spyOn(this, 'logoff');
}
logoff() { }
}
This test code used to work, but now using spyOn() gives an error:
Argument of type '"logoff"' is not assignable to parameter of type 'this["logoff"] extends Function ? "logoff" : never'.ts(2345)
It's easily circumventable using as:
spyOn(this as AuthServiceMock, 'logoff');
But this shouldn't be necessary, so I thought I'd share my findings.
Interesting usage, I am not sure about the issue, but have you tried to use export const AuthServiceMock = jasmine.createSpyObj<Auth service>('AuthService',['logoff'])?
Normally I keep mocks inside the spec.
Anyway, I'll try to reproduce the issue a bit later
I believe this is a Typescript error, I was able to get a minimal repro case of what's happening with this example:
export class MyClass {
constructor() {
getMethod(this, 'logoff') // Error
getMethod(this as MyClass, 'logoff') // OK
}
logoff() {}
}
function getMethod<T, K extends keyof T = keyof T>(
object: T,
method: T[K] extends Function ? K : never,
) {
return object[method];
}
I've created https://github.com/microsoft/TypeScript/issues/32258 on the main TS repo
@FDIM:
Interesting usage, I am not sure about the issue, but have you tried to use
export const AuthServiceMock = jasmine.createSpyObj<Auth service>('AuthService',['logoff'])?
I'm using this mock with Angular's dependency injection mechanism, which needs types. But there are definitely cases where this is a viable solution.
Normally I keep mocks inside the spec.
I do as well for most mocks. Only with a handful of them I noticed I was duplicating mock behavior, so I created separate mock classes.
@kolodny:
I believe this is a Typescript error, I was able to get a minimal repro case of what's happening with this example:
...
I've created microsoft/TypeScript#32258 on the main TS repo
Ah, awesome. Thanks!
Do you have any updates? I can see the TS bug has been closed down with no resolution.
@FDIM @kolodny
This is still blocked by https://github.com/microsoft/TypeScript/issues/33179
I took a stab at it but can't seem to get it to work at this time, feel free to take over on this effort:
diff --git a/types/jasmine/index.d.ts b/types/jasmine/index.d.ts
index 40706dec76..398f4accbf 100644
--- a/types/jasmine/index.d.ts
+++ b/types/jasmine/index.d.ts
@@ -160,7 +160,10 @@ interface DoneFn extends Function {
* @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>(object: T, method: keyof T): jasmine.Spy;
+declare function spyOn<T, K extends keyof T = keyof T>(
+ object: Record<K, Function>,
+ method: keyof T extends never ? string : K,
+): jasmine.Spy;
/**
* Install a spy on a property installed with `Object.defineProperty` onto an existing object.
diff --git a/types/jasmine/jasmine-tests.ts b/types/jasmine/jasmine-tests.ts
index c6220c548f..9e6beb3654 100644
--- a/types/jasmine/jasmine-tests.ts
+++ b/types/jasmine/jasmine-tests.ts
@@ -339,6 +339,15 @@ describe("A spy", () => {
foo.setBaz(789);
});
+ it('works with this in the constructor', () => {
+ class MyClass {
+ constructor() {
+ spyOn(this, 'logoff');
+ }
+ logoff() {}
+ }
+ });
+
it("tracks that the spy was called", () => {
expect(foo.setBar).toHaveBeenCalled();
});
diff --git a/types/jasmine/ts3.1/index.d.ts b/types/jasmine/ts3.1/index.d.ts
index e5f6799418..3f9df3a1e8 100644
--- a/types/jasmine/ts3.1/index.d.ts
+++ b/types/jasmine/ts3.1/index.d.ts
@@ -157,9 +157,11 @@ interface DoneFn extends Function {
* @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 Function ? K : never,
+declare function spyOn<T, K extends keyof T>(
+ object: Record<K, Function>,
+ method: keyof T extends never ? string : K,
): jasmine.Spy<
+ keyof T extends never ? any :
T[K] extends InferableFunction ? T[K] :
T[K] extends {new (...args: infer A): infer V} ? (...args: A) => V :
T[K] extends Function ? InferableFunction : never
Most helpful comment
I believe this is a Typescript error, I was able to get a minimal repro case of what's happening with this example:
I've created https://github.com/microsoft/TypeScript/issues/32258 on the main TS repo