0

I have this case where I want to test a function with some specific this. But typescript either won't let me add the method to the object, or if I define it as any then my interface is not being used.

example:

import getMostPeersTorrentsFromDateRange from './index'
import Db from '../Db'

test('getMostPeersTorrentsFromDateRange', async () => {
  const db = Db() as any
  db.getMostPeersTorrentsFromDateRange = getMostPeersTorrentsFromDateRange
  const torrents = await db.getMostPeersTorrentsFromDateRange({startDate: '2019-03-03', endDate: '2019-03-08', limit: 100})
})

and in the other file

import {Torrent} from '../interfaces'

interface GetMostPeersTorrentsFromDateRange {
  (GetMostPeersTorrentsFromDateRangeSettings: {
    startDate: string,
    endDate: string,
    limit: number
  }): Promise<Torrent[]>
}

const getMostPeersTorrentsFromDateRange: GetMostPeersTorrentsFromDateRange = async function ({startDate, endDate, limit}) {
  return []
}

export default getMostPeersTorrentsFromDateRange

How can I achieve what I'm trying to do with the least amount of code repetition? I don't want to define getMostPeersTorrentsFromDateRange twice, and I don't really want to import/export it either.

user12341234
  • 1,137
  • 2
  • 10
  • 22

1 Answers1

1

I suspect, that error arise from line

db.getMostPeersTorrentsFromDateRange = getMostPeersTorrentsFromDateRange

This issue and workaround described here. In short, ts knows, that db hasn't property getMostPeersTorrentsFromDateRange and reports error.

For your specific purpose I suggest not adding property getMostPeersTorrentsFromDateRange but use call method of all JS functions, which allows to provide arbitrary this and preserves type safety.

getMostPeersTorrentsFromDateRange.call(db, {startDate: '1', endDate: '2', limit: 3})

Here is playground

Fyodor Yemelyanenko
  • 11,264
  • 1
  • 30
  • 38
  • using call still seems to lose the interface, I can put limit as a string and get no type error. my goal is to enforce the interface of the function but I can't figure out how to do it. – user12341234 Jan 26 '20 at 12:08
  • No, `call` preserves types. Look at playfround link I've provided. Maybe you've not removed `DB() as any` typecast or use old version of typescript. – Fyodor Yemelyanenko Jan 26 '20 at 12:14
  • I'm using 3.7 and I have remove `as any`. and it's still not working. It is working in playground but not in my environment for some reason. I do have "strict": false not sure if that's the problem but I can't enable it. – user12341234 Jan 26 '20 at 12:45