fp-ts
fp-ts copied to clipboard
Support for typed key in record.filter
🚀 Feature request
Example:
type UserId = '1' | '2' | '3';
declare const users: Record<UserId, User>;
const filteredUsers = pipe(users, record.filter(...));
Current Behavior
Above example produces Record<string, User>
Desired Behavior
Above example produces Record<UserId, User>
Suggested Solution
Add these signatures:
<K extends string, A, B extends A>(refinement: Refinement<A, B>): (fa: Record<K, A>) => Record<K, B>
<K extends string, A>(predicate: Predicate<A>): (fa: Record<K, A>) => Record<K, A>
Who does this impact? Who is this for?
Useful with advanced type usage - limited set of keys, or for example in our case using branded strings for marking entity IDs.
Your environment
| Software | Version(s) |
|---|---|
| fp-ts | 2.7.0 |
| TypeScript | 4.4.3 |
If you are filtering (unlike mapping) you can get less entries, returning Record<UserId, User> is not safe
If you are filtering (unlike mapping) you can get less entries, returning
Record<UserId, User>is not safe
Yep that is technically true, but Typescript is a compromise between usability and correctness (and so is fp-ts - current signature is not safe too). And in this particular case, I still think my suggestion would improve the correctness - Record<string, something> will seem to contain all possible strings, while with my suggestion it will at least limit to previously known keys.
And from pragmatic point of view, I think many people use Record<K, V> where you should theoretically have Partial<Record<K, V>> just to keep things simple, and current implementation would force them to use type assertions which are even more unsafe or implement other workarounds when they need to filter a record.