- 
                Notifications
    You must be signed in to change notification settings 
- Fork 468
Description
- dom-testing-libraryversion: 5.2.1
- react-testing-libraryversion: 8.0.1
- reactversion: 16.8.6
- nodeversion: 10.16.0
- npm(or- yarn) version: npm(6.9.0), yarn(1.16.0)
Relevant code or config:
const { findByText } = render(<App />);
const button = await findByText( // TS error: "Expected 1-2 arguments, but got 3"
  /inc/i,
  {},
  {
    timeout: 100
  }
);What you did:
Used bound findByText function returned by render from @testing-library/react with waitForElementOptions argument.
What happened:
Typescript threw an error Expected 1-2 arguments, but got 3
Reproduction:
https://codesandbox.io/s/uok74
Take a look at App.test.tsx.
Problem description:
waitForElementOptions argument is not considered for bound functions type here: 
dom-testing-library/typings/get-queries-for-element.d.ts
Lines 4 to 13 in 349f497
| export type BoundFunction<T> = T extends ( | |
| attribute: string, | |
| element: HTMLElement, | |
| text: infer P, | |
| options: infer Q, | |
| ) => infer R | |
| ? (text: P, options?: Q) => R | |
| : T extends (a1: any, text: infer P, options: infer Q) => infer R | |
| ? (text: P, options?: Q) => R | |
| : never | 
Suggested solution:
Another signature should be added that supports waitForElementOptions argument to the type linked above.
I tried to do that, but my attempt failed. Here's what I've tried:
export type BoundFunction<T> = T extends (
  attribute: string,
  element: HTMLElement,
  text: infer P,
  options: infer Q,
) => infer R
  ? (text: P, options?: Q) => R
  : T extends (a1: any, text: infer P, options: infer Q, waitForElementOptions: infer S) => infer R
  ? (text: P, options?: Q, waitForElementOptions?: S) => R
  : T extends (a1: any, text: infer P, options: infer Q) => infer R
  ? (text: P, options?: Q) => R
  : neverNote these 2 lines that I've added:
: T extends (a1: any, text: infer P, options: infer Q, waitForElementOptions: infer S) => infer R
? (text: P, options?: Q, waitForElementOptions?: S) => RIt fixed the case with bound find* queries, now they accept waitForElementOptions argument, but it breaks proper typechecking for get* and other bound queries, that accept fewer arguments. For some reason typescript uses this signature for them too, which results in ability to call them with more arguments than they accept.
Example:
const { getByText } = render(<App />);
const button = getByText( // TS should throw error here, but doesn't
  /inc/i,
  {},
  {
    timeout: 100
  }
);I probably don't fully understand how assignability rules work for function signatures in conditional types in Typescript(I think it should be from top to bottom, from more to less specific signatures). Would be great if someone could find a solution to this.