Skip to content
This repository has been archived by the owner on Aug 8, 2020. It is now read-only.

Flow TestInterface does not accept exact context type #2

Open
gajus opened this issue Jun 28, 2018 · 6 comments
Open

Flow TestInterface does not accept exact context type #2

gajus opened this issue Jun 28, 2018 · 6 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@gajus
Copy link

gajus commented Jun 28, 2018

Description

Flow TestInterface does not accept exact context type.

Test Source

// @flow

/* eslint-disable ava/use-test, no-unused-vars */

import untypedTest from 'ava';
import type {
  TestInterface
} from 'ava';

type ServerType = {||};

const test: TestInterface<ServerType> = untypedTest;

Error Message & Stack Trace

Cannot assign untypedTest to test because inexact object type [1] is incompatible with exact ServerType [2] in type
argument Context [3].

        test/integration.js
          9│
         10│ type ServerType = {||};
         11│
    [2]  12│ const test: TestInterface<ServerType> = untypedTest;
         13│

        node_modules/ava/index.js.flow
 [3][1] 461│ export interface TestInterface<Context = {}> {

Environment

Tell us which operating system you are using, as well as which versions of Node.js, npm, and AVA. Run the following to get it quickly:

node -e "var os=require('os');console.log('Node.js ' + process.version + '\n' + os.platform() + ' ' + os.release())"
ava --version
npm --version
Node.js v10.5.0
darwin 17.4.0
1.0.0-beta.6
6.1.0
@gajus
Copy link
Author

gajus commented Jun 28, 2018

There is something even more wrong with this:

// @flow

import untypedTest from 'ava';
import type {
  TestInterface
} from 'ava';

type ContextType = {
  server: ServerType
};

const test: TestInterface<ContextType> = untypedTest;
Cannot assign untypedTest to test because property server is missing in object type [1] but exists in ContextType [2] in
type argument Context [3].

        test/integration.js
         24│   server: ServerType
         25│ };
         26│
    [2]  27│ const test: TestInterface<ContextType> = untypedTest;
         28│
         29│ const SERVER_URL = 'http://127.0.0.1';
         30│

        node_modules/ava/index.js.flow
 [3][1] 461│ export interface TestInterface<Context = {}> {

@novemberborn
Copy link
Member

Which Flow version is this? I'm pretty sure this worked when I wrote the definition, but I don't use Flow so I may have overlooked this.

Fixes to the definition are most welcome. Would be good to have a type-check regression test for this too.

@vinsonchuong
Copy link

I was able to work around this error by casting to any first:

import untypedTest from 'ava'

const test: TestInterface<{ directory: string }> = (untypedTest: any)

I'm using Flow v0.77.0 and played around for a while with the type definition, but haven't yet been able to find a fix.

@novemberborn
Copy link
Member

novemberborn commented Aug 1, 2018

Thanks for your comment @vinsonchuong. It prompted me to double-check our Flow recipe, and your solution is what's documented there: https://github.com/avajs/ava/blob/master/docs/recipes/flow.md#typing-tcontext

I'd still love if this wasn't necessary, of course.

@gajus
Copy link
Author

gajus commented Jan 10, 2019

@vinsonchuong Is there a more recent solution to this?

@sindresorhus sindresorhus transferred this issue from avajs/ava May 2, 2019
@sindresorhus sindresorhus added bug Something isn't working help wanted Extra attention is needed labels May 2, 2019
@langri-sha
Copy link

langri-sha commented Jun 17, 2019

Things are working as expected and an error is thrown because untypedTest already has an invariant type argument provided. This works const test: TestInterface<{}> = untypedTest;, but for all other assignments it is unsound and untypedTest must be downcast to any at your discretion.

I believe an alternative would be to set any explicitly by default by exporting TypeInterface<any>. This should permit const test: TestInterface<MyContext> = untypedTest; and would not throw type errors for cases users aren't interested to have type soundness in their contexts like so:

import test from 'ava'

test.before('no type checking on context', t => {
  t.context.foo = 'bar'
})

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants