Chainable API
I just discovered this library and it looks great. What do you think of supporting a chainable API too?
Pure functions are nice but when a developer needs to use multiple methods in a row it gets annoying to have to define intermediary variables or to nest function calls. JavaScript doesn't have a pipeline operator but prototypes can be safely augmented these days using symbols (rather than strings which can cause conflicts because they are not unique).
Example
import $ from 'es-toolkit/$';
import 'es-toolkit/$/array/chunk';
// Splits an array of numbers into sub-arrays of length 2
[1, 2, 3, 4, 5][$.chunk](2);
// Returns: [[1, 2], [3, 4], [5]]
// Splits an array of strings into sub-arrays of length 3
['a', 'b', 'c', 'd', 'e', 'f', 'g'][$.chunk](3);
// Returns: [['a', 'b', 'c'], ['d', 'e', 'f'], ['g']]
Implementation
Augmenting modules should be able to be programmatically generated from pure functions (e.g. using ts-morph):
// es-toolkit/$.ts
export interface Symbols {};
export default {} as Symbols;
// es-toolkit/$/.symbols/chunk.ts
import $ from 'es-toolkit/$.ts';
const key = 'chunk';
const value = Symbol(`es-toolkit/${key}`);
declare module 'es-toolkit/$.ts' {
interface Symbols {
[key]: typeof value;
}
}
Object.defineProperty($, key, { value });
// es-toolkit/$/array/chunk.ts
import 'es-toolkit/.symbols/chunk';
import { chunk } from 'es-toolkit/array/chunk';
const key = $.chunk;
function value<T>(this: T[], size: number): T[] {
return chunk(this, size);
}
declare global {
interface Array<T> {
[key](size: number): T[];
}
}
Object.defineProperty(Array.prototype, key, { value });
Do modifications to the Array.prototype make the sideEffects become true?
Do modifications to the Array.prototype make the
sideEffectsbecome true?
I'm not familiar with that flag. Is that a webpack specific flag? I think it would, but the side-effects modules could be published under a different package name while reusing code to avoid such.
After looking at some docs it looks like this can be set to true for only some modules. e.g.
"sideEffects": ["./src/$/**/*.ts"]
mutating Array.prototype doesn't sound like the best idea to me
mutating Array.prototype doesn't sound like the best idea to me
Understandably IMO. Historically this is considered unsafe but with the introduction of Symbol in JavaScript this can now be done safely without name collisions (as is possible with String-based keys but not with unique Symbol-based keys). This is commonly done today with polyfills (e.g. via zloirock/core-js: Standard Library). It is this same polyfill idea/process but applied to user-defined prototype methods using Symbol keys instead of TC39-define prototype methods using String keys.