So in TS we have the generic identity function:
const identity = <A>(a: A) => a;
Of course, if we invoke that function then TS is able to infer the type parameter A
:
declare const baz: string
const foo = identity("bar") // A = "bar", so typeof foo = "bar"
const bar = identity(baz) // A = string, so typeof bar = string
But if I try something like
import { foldMap } from "fp-ts/Array"
import { getMonoidAll, Predicate } from "fp-ts/Predicate"
declare const predicates: Predicate<string>[];
const concatPredicates = foldMap(getMonoidAll<string>())(identity);
then TS tells me that "Type A
is not assignable to type Predicate<string>
because it infers
typeof foldMap(getMonoidAll<string>()) = <A>(f: (a: A) => Predicate<string>) =>
(fa: A[]) => Predicate<string>
and it doesn't understand that if A = Predicate<string>
then the identity function works and the construct above expects an input of type Predicate<string>[]
.
Of course, instead of using identity
I could use (a: Predicate<string>) => a
, but having to do that feels a bit cumbersome and I would really love to be able to take advantage of the generic nature of the identity
function.
Is there any way to do so? Is there any way I can provide a type hint for a function reference? After all, the unnaturally verbose looking (a: Predicate<string>) => identity(a)
works because in that case TS infers A = Predicate<string>
.
CodePudding user response:
I’m not sure why TypeScript can’t infer the type of identity
correctly, but you could do this as a workaround:
const concatPredicates = foldMap(getMonoidAll<string>())(
identity as (a: Predicate<string>) => Predicate<string>
);
Alternatively (and what I prefer for this scenario), you could use concatAll
:
import { concatAll } from "fp-ts/Monoid";
const concatPredicates = concatAll(getMonoidAll<string>());