I am embarking on my first attempt to create a simple interface in TypeScript, and I find myself questioning every step along the way.
The core question that troubles me is: How can I best describe this straightforward Jest matcher extension?
/**
* @param {*} v Any value
*/
function just (v) {
return {
fmap: f => just(f(v))
}
}
expect.extend({
/** Compare the two values inside two functors with Object.is
* @method
* @augments jest.Matchers
* @param {*} actual The functor you want to test.
* @param {*} expected The functor you expect.
*/
functorToBe(actual, expected) {
const actualValue = getFunctorValue(actual)
const expectedValue = getFunctorValue(expected)
const pass = Object.is(actualValue, expectedValue)
return {
pass,
message () {
return `expected ${actualValue} of ${actual} to ${pass ? '' : 'not'} be ${expectedValue} of ${expected}`
}
}
}
})
test('equational reasoning (identity)', () => {
expect(just(1)).functorToBe(just(1))
})
Although I attempted to implement this, I have uncertainties regarding the usage of generic types:
import { Matchers } from 'jest'
interface Functor<T> {
(value?: any): {
fmap: (f: value) => Functor<T>
}
}
interface Matchers<R> {
functorToBe(actual: Functor<T>, expected: Functor<T>): R
}
Reference: JSDoc document object method extending other class
The key point of the Jest type definition for Matchers<R>
:
/**
* The `expect` function is used every time you want to test a value.
* You will rarely call `expect` by itself.
*/
interface Expect {
/**
* The `expect` function is used every time you want to test a value.
* You will rarely call `expect` by itself.
*
* @param actual The value to apply matchers against.
*/
<T = any>(actual: T): Matchers<T>;
/**
* You can use `expect.extend` to add your own matchers to Jest.
*/
extend(obj: ExpectExtendMap): void;
// etc.
}
This situation is quite perplexing. The only index.d.ts found in the jest repository is https://github.com/facebook/jest/blob/master/packages/jest-editor-support/index.d.ts, which differs from what I see in vscode, located at https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/jest/index.d.ts#L471.