In the TypeScript core libraries, Array.filter has two signatures:
filter<S extends T>(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): S[];
filter(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): T[];
I understand the first signature - it lets a type assertion predicate narrow the type of the array.
However, the second signature seems like it make the predicate return boolean instead of unknown. I understand that JS is more permissive than this and will coerce the value into a boolean, but TypeScript doesn't seem to usually encourage implicit conversions.
Changing it to boolean would seem to prevent more bugs, ie:
// Because the return type is unknown, TS silently accepts this unintentional number | boolean return type
[1,2,3,4,5].filter(el => someMap.get(el) ?? 0 > 1) // equivalent to someMap.get(el) ?? (0 > 1)
What is the justification behind this signature?
The same question applies to some and any, but not to find.