help wanted
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([]));
});
});