0

I have an interface like this:

export interface BarsParams {
  timeframe: string;
  start?: string;
  end?: string;
  limit?: number;
  page_token?: string;
  adjustment?: Adjustment;
  asof?: string;
  feed?: string;
}

Then I have a function that takes as argment params: BarsParams where I want to iterate through the key-value pairs of what I presumed was a regular object:

export function getBars(symbol: string, params: BarsParams) {
  let url = new URL(`${symbol}/bars`, endpoints.STOCKS_URL.href).href;
  for (const [key, value] of params) {
    //do something
  }
  let body = params;
  try {
    const response = fetch(url, new RequestInit(Method.Get, body));
    return response;
  } catch (error) {
    console.log(error);
  }
}

In the function call I pass the search params like an "object" as follows:

getBars('someSymbol', {timeframe: '59Min', limit: 10}).then(...)

However, TypeScript throws:

Type 'BarsParams' must have a '[Symbol.iterator]()' method that returns an iterator.ts(2488)

Why does TypeScript not infer that this is an object with an iterator and how can it be solved conveniently?

  • TypeScript is right: you need to do `for (const [key, value] of Object.entries(params))`. – Lauren Yim Aug 15 '22 at 21:13
  • But that isn't an object with an iterator? – kelsny Aug 15 '22 at 21:13
  • You need to call `Object.entries(params)` to iterate over key/value. A plain javascript object is not an iterator. – ShamPooSham Aug 15 '22 at 21:14
  • Thank you for your answer @cherryblossom. But why does TypeScript not infer this based on the shape of the passed parameters? –  Aug 15 '22 at 21:15
  • @kelly Plain objects like `BarsParams` are not iterable if they lack the `Symbol.iterator` method. Try doing `for (const _ of {}) {}` and you’ll get a TypeError. – Lauren Yim Aug 15 '22 at 21:15
  • 1
    I’m a bit confused about what you’re expecting TypeScript to do. TypeScript never infers that you should call a function to make your code work (well, not in this situation). It’s telling you that you can’t iterate a `BarsParams`. – Lauren Yim Aug 15 '22 at 21:17
  • 1
    @javascript-scholar You need to understand that typescript doesn't add anything in runtime in this example, it just infers things statically during development to give you warnings before you run the code. Javascript requires that the right hand side of the `of`-keyword has a `[Symbol.iterator]()` method, which not all javascript objects do. It sounds like you assume typescript should do some magic in the resulting javascript so that it becomes an iterator, but it doesn't do that. It's not meant to do that. – ShamPooSham Aug 15 '22 at 21:21
  • Thanks a lot ShamPooSham. That was what I was expecting and I appreciate you correcting my understanding. –  Aug 15 '22 at 21:23

0 Answers0