Flow, a static type checker for JavaScript, version 0.38.0
Perhaps I'm just having one of those days and can't see the woods for the trees.
Nevertheless why does this compile:
function identity<T>(arg: T): T {
return arg;
}
const id: <T>(arg: T) => T = identity;
but this doesn't?
const identity = <T>(arg: T) => arg;
const id: <T>(arg: T) => T = identity;
Produces:
inconsistent use of library definitions
14: const identity = <T>(arg: T) => arg;
^^^ T. This type is incompatible with
16: const id: <T>(arg: T) => T = identity;
^^^^^^^^ some incompatible instantiation of `T`
Hmm, writing const identity = <T>(arg: T): T => arg works. I'm not sure why leaving off the explicit return type (you've got <T>(arg: T) => arg) breaks though.
Interestingly, flow suggest seems to break with the <T>(arg: T) => arg version; it just won't give me any suggestions.
Indeed, you should annotate return type explicitly.
I have a similar problem with this. In flow v0.75.0, the following patterns work and they all produce the same type signature: <T> (T) => T (see here)
// @flow
// function with implicit return type
function identity1<T>(x: T) {
return x;
}
// function with explicit return type
function identity2<T>(x: T): T {
return x;
}
// function expression with implicit return type
const identity3 = function<T>(x: T) {
return x;
};
// function expression with explicit return type
const identity4 = function<T>(x: T): T {
return x;
};
// arrow with implicit return type
const identity5 = <T>(x: T) => x;
// arrow with explicit return type
const identity6 = <T>(x: T): T => x;
console.log(identity1(123), identity1('123'));
console.log(identity2(123), identity2('123'));
console.log(identity3(123), identity3('123'));
console.log(identity4(123), identity4('123'));
console.log(identity5(123), identity5('123'));
console.log(identity6(123), identity6('123'));
But if I try to extract the type signature and use it as a standalone type for the function, it fails (see here)
type ID = <T>(T) => T;
const identity: ID = x => x;
2: const identity: ID = x => x;
^ Cannot assign function to `identity` because `T` [1] is incompatible with `T` [2] in the return value.
References:
1: type ID = <T>(T) => T;
^ [1]
1: type ID = <T>(T) => T;
^ [2]
However, I can make it work if I add generic type T to function definition (see here)
// @flow
type ID = <T>(T) => T;
const identity: ID = <T>(x) => x;
Can anyone explain what's going on here?
Most helpful comment
I have a similar problem with this. In flow v0.75.0, the following patterns work and they all produce the same type signature:
<T> (T) => T(see here)But if I try to extract the type signature and use it as a standalone type for the function, it fails (see here)
However, I can make it work if I add generic type
Tto function definition (see here)Can anyone explain what's going on here?