Skip to content

SpyObj<T>[keyof T] not resolving to the type SpyObj members (Jasmine typings) #25181

Closed
@mprobst

Description

@mprobst

TypeScript Version: 2.9.2

Code

interface Spy {
  (...params: any[]): any;

  identity: string;
  and: Function;
  mostRecentCall: {args: any[];};
  argsForCall: any[];
}

type SpyObj<T> = T&{
  [k in keyof T]: Spy;
}

declare function createSpyObj<T>(
    name: string, names: Array<keyof T>): SpyObj<T>;

/**
 * Creates a jasmine mock where every given method returns the spy object.
 */
function mock<T>(spyName: string, methodNames: Array<keyof T>): SpyObj<T> {
  const spyObj = createSpyObj<T>(spyName, methodNames);
  for (const methodName of methodNames) {
    spyObj[methodName].and.returnValue(1);  // fails, Property 'and' does not exist on type 'SpyObj<T>[keyof T]'.
  }
  return spyObj;
}

Expected behavior:

In TS2.8, spyObj[methodName] above was any, allowing and to be referenced on it. Ideally, this would figure out that all members of spyObj must at least be a Spy.

Actual behavior:

In TS 2.9, there's a type SpyObj<T>[keyof T], but apparently it does not resolve to Spy?

Playground Link:

http://www.typescriptlang.org/play/#src=%0Ainterface%20Spy%20%7B%0A%20%20(...params%3A%20any%5B%5D)%3A%20any%3B%0A%0A%20%20identity%3A%20string%3B%0A%20%20and%3A%20Function%3B%0A%20%20mostRecentCall%3A%20%7Bargs%3A%20any%5B%5D%3B%7D%3B%0A%20%20argsForCall%3A%20any%5B%5D%3B%0A%7D%0A%0Atype%20SpyObj%3CT%3E%20%3D%20T%26%7B%0A%20%20%5Bk%20in%20keyof%20T%5D%3A%20Spy%3B%0A%7D%0A%0Adeclare%20function%20createSpyObj%3CT%3E(%0A%20%20%20%20name%3A%20string%2C%20names%3A%20Array%3Ckeyof%20T%3E)%3A%20SpyObj%3CT%3E%3B%0A%0A%2F**%0A%20*%20Creates%20a%20jasmine%20mock%20where%20every%20given%20method%20returns%20the%20spy%20object.%0A%20*%2F%0Afunction%20mock%3CT%3E(spyName%3A%20string%2C%20methodNames%3A%20Array%3Ckeyof%20T%3E)%3A%20SpyObj%3CT%3E%20%7B%0A%20%20const%20spy%20%3D%20createSpyObj%3CT%3E(spyName%2C%20methodNames)%3B%0A%20%20for%20(const%20methodName%20of%20methodNames)%20%7B%0A%20%20%20%20spy%5BmethodName%5D.and.returnValue(spy)%3B%0A%20%20%7D%0A%20%20return%20spy%3B%0A%7D%0A

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions