Galooshi/import-js

Flow's generic types

Open

#489 opened on Mar 17, 2018

View on GitHub
 (1 comment) (0 reactions) (0 assignees)JavaScript (70 forks)batch import
help wanted

Repository metrics

Stars
 (519 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

It seems that import-js does not recognize flow's generic types:

function Fn<T>(x: T): T { return x; }

It cause import-js to insert:

import { T } from "lodash/fp";

Though T is not a function, and it is already defined in this code snippet. Here is the generic's doc: https://flow.org/en/docs/types/generics/

I tried to fix this, but it is a too complex task. I see that "babylon" parses generic type definitions correctly. I think we need to add generic type declarations to the context so that we can filter this names in "lib/findUndefinedIdentifiers.js". But we must treat js names and flow names in the context differently. If T is used as a js name then we need to import it. If T is used as a flow type then it is already defined.

This are the tests I wrote for this task:

describe('should recognize flow\'s generic type', () => {
  test('function statement', () => {
    expect(findUndefinedIdentifiers(parse(`
      function Fn<T>(x: T): T {
        return x;
      }
    `))).toEqual(new Set([]));
  });

  test('function expression', () => {
    expect(findUndefinedIdentifiers(parse(`
      const Fn = function Fn<T>(x: T): T {
        return x;
      };
    `))).toEqual(new Set([]));
  });

  test('arrow function', () => {
    expect(findUndefinedIdentifiers(parse(`
      const Fn = <T>(x: T): T => x;
    `))).toEqual(new Set([]));
  });

  test('type statement', () => {
    expect(findUndefinedIdentifiers(parse(`
      type Some<T> = T[];
    `))).toEqual(new Set([]));
  });

  test('class', () => {
    expect(findUndefinedIdentifiers(parse(`
      class Some<T> {
        prop: T;
        constructor(param: T) {
          this.prop = param;
        }
      }
    `))).toEqual(new Set([]));
  });

  test('interface', () => {
    expect(findUndefinedIdentifiers(parse(`
      interface Some<T> {
        foo: T,
        bar: T
      }
    `))).toEqual(new Set([]));
  });
});

Contributor guide