style: Apply prettier

This commit is contained in:
Sojin Park 2024-08-11 10:54:13 +09:00
parent 5260d5b81b
commit be4162dc19
101 changed files with 534 additions and 551 deletions

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from 'vitest';
import { getBundleSize } from "./utils/getBundleSize" import { getBundleSize } from './utils/getBundleSize';
describe('camelCase bundle size', () => { describe('camelCase bundle size', () => {
it('lodash-es', async () => { it('lodash-es', async () => {
@ -10,5 +10,5 @@ describe('camelCase bundle size', () => {
it('es-toolkit', async () => { it('es-toolkit', async () => {
const bundleSize = await getBundleSize('es-toolkit', 'camelCase'); const bundleSize = await getBundleSize('es-toolkit', 'camelCase');
expect(bundleSize).toMatchInlineSnapshot(`297`); expect(bundleSize).toMatchInlineSnapshot(`297`);
}) });
}); });

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from 'vitest';
import { getBundleSize } from "./utils/getBundleSize" import { getBundleSize } from './utils/getBundleSize';
describe('chunk bundle size', () => { describe('chunk bundle size', () => {
it('lodash-es', async () => { it('lodash-es', async () => {
@ -10,10 +10,10 @@ describe('chunk bundle size', () => {
it('es-toolkit', async () => { it('es-toolkit', async () => {
const bundleSize = await getBundleSize('es-toolkit', 'chunk'); const bundleSize = await getBundleSize('es-toolkit', 'chunk');
expect(bundleSize).toMatchInlineSnapshot(`238`); expect(bundleSize).toMatchInlineSnapshot(`238`);
}) });
it('es-toolkit/compat', async () => { it('es-toolkit/compat', async () => {
const bundleSize = await getBundleSize('es-toolkit/compat', 'chunk'); const bundleSize = await getBundleSize('es-toolkit/compat', 'chunk');
expect(bundleSize).toMatchInlineSnapshot(`307`); expect(bundleSize).toMatchInlineSnapshot(`307`);
}) });
}); });

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from 'vitest';
import { getBundleSize } from "./utils/getBundleSize" import { getBundleSize } from './utils/getBundleSize';
describe('difference bundle size', () => { describe('difference bundle size', () => {
it('lodash-es', async () => { it('lodash-es', async () => {
@ -10,5 +10,5 @@ describe('difference bundle size', () => {
it('es-toolkit', async () => { it('es-toolkit', async () => {
const bundleSize = await getBundleSize('es-toolkit', 'difference'); const bundleSize = await getBundleSize('es-toolkit', 'difference');
expect(bundleSize).toMatchInlineSnapshot(`90`); expect(bundleSize).toMatchInlineSnapshot(`90`);
}) });
}); });

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from 'vitest';
import { getBundleSize } from "./utils/getBundleSize" import { getBundleSize } from './utils/getBundleSize';
describe('isEqual bundle size', () => { describe('isEqual bundle size', () => {
it('lodash-es', async () => { it('lodash-es', async () => {
@ -10,5 +10,5 @@ describe('isEqual bundle size', () => {
it('es-toolkit', async () => { it('es-toolkit', async () => {
const bundleSize = await getBundleSize('es-toolkit', 'isEqual'); const bundleSize = await getBundleSize('es-toolkit', 'isEqual');
expect(bundleSize).toMatchInlineSnapshot(`2930`); expect(bundleSize).toMatchInlineSnapshot(`2930`);
}) });
}); });

View File

@ -17,4 +17,4 @@ export async function getBundleSize(pkg: 'lodash-es' | 'es-toolkit' | 'es-toolki
}); });
return Buffer.from(bundled.outputFiles![0].contents).byteLength; return Buffer.from(bundled.outputFiles![0].contents).byteLength;
} }

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from 'vitest';
import { getBundleSize } from "./utils/getBundleSize" import { getBundleSize } from './utils/getBundleSize';
describe('zipObjectDeep bundle size', () => { describe('zipObjectDeep bundle size', () => {
it('lodash-es', async () => { it('lodash-es', async () => {
@ -10,5 +10,5 @@ describe('zipObjectDeep bundle size', () => {
it('es-toolkit/compat', async () => { it('es-toolkit/compat', async () => {
const bundleSize = await getBundleSize('es-toolkit/compat', 'zipObjectDeep'); const bundleSize = await getBundleSize('es-toolkit/compat', 'zipObjectDeep');
expect(bundleSize).toMatchInlineSnapshot(`992`); expect(bundleSize).toMatchInlineSnapshot(`992`);
}) });
}); });

View File

@ -4,20 +4,20 @@ import { get as getLodash } from 'lodash';
describe('get with string', () => { describe('get with string', () => {
bench('es-toolkit/get', () => { bench('es-toolkit/get', () => {
getToolkit({ a: { b: 3 } }, 'a.b') getToolkit({ a: { b: 3 } }, 'a.b');
}) });
bench('lodash/get', () => { bench('lodash/get', () => {
getLodash({ a: { b: 3 } }, 'a.b') getLodash({ a: { b: 3 } }, 'a.b');
}) });
}) });
describe('get with string array', () => { describe('get with string array', () => {
bench('es-toolkit/get', () => { bench('es-toolkit/get', () => {
getToolkit({ a: { b: 3 } }, ['a', 'b']) getToolkit({ a: { b: 3 } }, ['a', 'b']);
}) });
bench('lodash/get', () => { bench('lodash/get', () => {
getLodash({ a: { b: 3 } }, ['a', 'b']) getLodash({ a: { b: 3 } }, ['a', 'b']);
}) });
}) });

View File

@ -28,7 +28,6 @@ import { isEqual as isEqualLodash } from 'lodash';
// }); // });
// }); // });
// describe('isEqual dates', () => { // describe('isEqual dates', () => {
// bench('es-toolkit/isEqual', () => { // bench('es-toolkit/isEqual', () => {
// isEqualToolkit(new Date('2020-01-01'), new Date('2020-01-01')); // isEqualToolkit(new Date('2020-01-01'), new Date('2020-01-01'));
@ -65,7 +64,7 @@ describe('isEqual objects', () => {
isEqualLodash({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 3 } }); isEqualLodash({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 3 } });
isEqualLodash({ a: 1, b: 2 }, { a: 1, b: 2 }); isEqualLodash({ a: 1, b: 2 }, { a: 1, b: 2 });
}); });
}) });
// describe('isEqual arrays', () => { // describe('isEqual arrays', () => {
// bench('es-toolkit/isEqual', () => { // bench('es-toolkit/isEqual', () => {
@ -78,5 +77,3 @@ describe('isEqual objects', () => {
// isEqualLodash([1, 2, 3], [1, 2, 4]); // isEqualLodash([1, 2, 3], [1, 2, 4]);
// }); // });
// }) // })

View File

@ -4,9 +4,9 @@ import { isMatch as isMatchLodash } from 'lodash';
describe('isMatch', () => { describe('isMatch', () => {
bench('es-toolkit/isMatch', () => { bench('es-toolkit/isMatch', () => {
isMatchToolkit({ a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 }, { a: { b: { c: 1 } } }) isMatchToolkit({ a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 }, { a: { b: { c: 1 } } });
}); });
bench('lodash/isMatch', () => { bench('lodash/isMatch', () => {
isMatchLodash({ a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 }, { a: { b: { c: 1 } } }) isMatchLodash({ a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 }, { a: { b: { c: 1 } } });
}); });
}); });

View File

@ -4,7 +4,7 @@ import { matches as matchesLodash } from 'lodash';
describe('matches', () => { describe('matches', () => {
bench('es-toolkit/matches', () => { bench('es-toolkit/matches', () => {
const isMatch = matchesToolkit({ a: { b: { c: 1 } } }) const isMatch = matchesToolkit({ a: { b: { c: 1 } } });
isMatch({ a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 }); isMatch({ a: { b: { c: 1, d: 2 }, e: 3 }, f: 4 });
}); });
bench('lodash/matches', () => { bench('lodash/matches', () => {

View File

@ -6,10 +6,10 @@ describe('property', () => {
bench('es-toolkit/property', () => { bench('es-toolkit/property', () => {
const getValue = propertyToolkit('a.b'); const getValue = propertyToolkit('a.b');
getValue({ 'a.b': 1, a: { b: 1 } }); getValue({ 'a.b': 1, a: { b: 1 } });
}) });
bench('lodash/property', () => { bench('lodash/property', () => {
const getValue = propertyLodash('a.b'); const getValue = propertyLodash('a.b');
getValue({ 'a.b': 1, a: { b: 1 } }); getValue({ 'a.b': 1, a: { b: 1 } });
}) });
}) });

View File

@ -27,11 +27,10 @@ This makes es-toolkit the most efficient in terms of bundle size, with some util
Our bundle size is measured using [esbuild 0.23.0](https://esbuild.github.io), by analyzing the size of code like the following: Our bundle size is measured using [esbuild 0.23.0](https://esbuild.github.io), by analyzing the size of code like the following:
```tsx ```tsx
import { chunk } from 'es-toolkit'; import { chunk } from 'es-toolkit';
// or import { chunk } from 'lodash-es'; // or import { chunk } from 'lodash-es';
console.log(chunk); console.log(chunk);
``` ```
See our [bundle size benchmark code](https://github.com/toss/es-toolkit/tree/main/benchmarks/bundle-size) for details. See our [bundle size benchmark code](https://github.com/toss/es-toolkit/tree/main/benchmarks/bundle-size) for details.

View File

@ -22,13 +22,12 @@ es-toolkit은 현대적인 구현을 가지고 있기 때문에, 다른 라이
| [pick](./reference/object/pick.md) | 657 bytes | 3860 bytes | -83.0% | | [pick](./reference/object/pick.md) | 657 bytes | 3860 bytes | -83.0% |
| [zip](./reference/array/zip.md) | 797 bytes | 1790 bytes | -55.5% | | [zip](./reference/array/zip.md) | 797 bytes | 1790 bytes | -55.5% |
## 번들 사이즈 측정 방법 ## 번들 사이즈 측정 방법
[esbuild 0.23.0](https://esbuild.github.io)로 번들 사이즈를 측정하고 있어요. 아래와 같은 코드를 사용해요. [esbuild 0.23.0](https://esbuild.github.io)로 번들 사이즈를 측정하고 있어요. 아래와 같은 코드를 사용해요.
```tsx ```tsx
import { chunk } from 'es-toolkit'; import { chunk } from 'es-toolkit';
// or import { chunk } from 'lodash-es'; // or import { chunk } from 'lodash-es';
console.log(chunk); console.log(chunk);

View File

@ -37,4 +37,4 @@ const result = difference(array1, array2);
| | [번들 사이즈](../../bundle-size.md) | [성능](../../performance.md) | | | [번들 사이즈](../../bundle-size.md) | [성능](../../performance.md) |
| ---------- | ----------------------------------- | ---------------------------- | | ---------- | ----------------------------------- | ---------------------------- |
| es-toolkit | 90 바이트 (92.4% 작음) | 9,317,227 회 (85% 빠름) | | es-toolkit | 90 바이트 (92.4% 작음) | 9,317,227 회 (85% 빠름) |
| lodash-es | 7,958 바이트 | 5,030,861 회 | | lodash-es | 7,958 바이트 | 5,030,861 회 |

View File

@ -7,11 +7,7 @@ JavaScript 언어에 포함된 [Array#flat](https://developer.mozilla.org/en-US/
## 인터페이스 ## 인터페이스
```typescript ```typescript
function flatMap<T, U, D extends number = 1>( function flatMap<T, U, D extends number = 1>(arr: T[], iteratee: (item: T) => U, depth?: D): Array<FlatArray<U[], D>>;
arr: T[],
iteratee: (item: T) => U,
depth?: D
): Array<FlatArray<U[], D>>;
``` ```
### 파라미터 ### 파라미터

View File

@ -11,10 +11,10 @@ function forEachRight<T>(arr: T[], callback: (value: T, index: number, arr: T[])
### 파라미터 ### 파라미터
- `arr`: (`T[]`): 순회할 배열. - `arr`: (`T[]`): 순회할 배열.
- `callback`: (`(value: T, index: number, arr: T[])`): 각 반복마다 호출될 함수예요. - `callback`: (`(value: T, index: number, arr: T[])`): 각 반복마다 호출될 함수예요.
- `value`: 배열에서 처리 중인 현재 요소. - `value`: 배열에서 처리 중인 현재 요소.
- `index`: 배열에서 처리 중인 현재 요소의 인덱스. - `index`: 배열에서 처리 중인 현재 요소의 인덱스.
- `arr`: `forEachRight` 함수가 호출된 배열. - `arr`: `forEachRight` 함수가 호출된 배열.
### 반환 값 ### 반환 값
@ -29,9 +29,9 @@ const array = [1, 2, 3];
const result: number[] = []; const result: number[] = [];
// forEachRight 함수를 사용하여 배열을 순회하며 각 요소를 결과 배열에 추가해요. // forEachRight 함수를 사용하여 배열을 순회하며 각 요소를 결과 배열에 추가해요.
forEachRight(array, (value) => { forEachRight(array, value => {
result.push(value); result.push(value);
}); });
console.log(result) // Output: [3, 2, 1]; console.log(result); // Output: [3, 2, 1];
``` ```

View File

@ -1,6 +1,6 @@
# without # without
배열에서 주어진 값을 제거한 새로운 배열을 만들어요. 배열에서 주어진 값을 제거한 새로운 배열을 만들어요.
값이 같은지는 [SameValueZero](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluezero) 기준으로 비교하기 때문에, `NaN`과도 사용할 수 있어요. 값이 같은지는 [SameValueZero](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluezero) 기준으로 비교하기 때문에, `NaN`과도 사용할 수 있어요.

View File

@ -1,6 +1,6 @@
# zipObject # zipObject
두 배열을 하나의 객체로 결합해요. 첫 번째 배열은 프로퍼티 이름을 나타내고, 두 번째 배열은 값을 나타내요. 두 배열을 하나의 객체로 결합해요. 첫 번째 배열은 프로퍼티 이름을 나타내고, 두 번째 배열은 값을 나타내요.
프로퍼티 이름을 나타내는 배열이 값을 나타내는 배열보다 길면, 값들은 `undefined`로 채워져요. 프로퍼티 이름을 나타내는 배열이 값을 나타내는 배열보다 길면, 값들은 `undefined`로 채워져요.

View File

@ -5,10 +5,7 @@
## 인터페이스 ## 인터페이스
```typescript ```typescript
function ary<F extends (...args: any[]) => any>( function ary<F extends (...args: any[]) => any>(func: F, n: number): (...args: any[]) => ReturnType<F>;
func: F,
n: number
): (...args: any[]) => ReturnType<F>;
``` ```
### 파라미터 ### 파라미터

View File

@ -25,14 +25,14 @@ function flattenObject(object: object): Record<string, any>;
const nestedObject = { const nestedObject = {
a: { a: {
b: { b: {
c: 1 c: 1,
} },
}, },
d: [2, 3] d: [2, 3],
}; };
const flattened = flattenObject(nestedObject); const flattened = flattenObject(nestedObject);
console.log(flattened); console.log(flattened);
// Output: // Output:
// { // {
// 'a.b.c': 1, // 'a.b.c': 1,

View File

@ -5,7 +5,7 @@ Count the occurrences of each item in an array based on a `mapper` function.
## Signature ## Signature
```typescript ```typescript
function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, number> function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, number>;
``` ```
### Parameters ### Parameters
@ -23,9 +23,8 @@ function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, numbe
import { countBy } from 'es-toolkit/array'; import { countBy } from 'es-toolkit/array';
const array = [1, 2, 3, 4, 5, 6]; const array = [1, 2, 3, 4, 5, 6];
const result = countBy(array, x => x % 2 === 0 ? 'even' : 'odd'); const result = countBy(array, x => (x % 2 === 0 ? 'even' : 'odd'));
console.log(result); console.log(result);
// Output: { 'odd': 3, 'even': 3 } // Output: { 'odd': 3, 'even': 3 }
``` ```

View File

@ -38,4 +38,4 @@ const result = difference(array1, array2);
| | [Bundle Size](../../bundle-size.md) | [Performance](../../performance.md) | | | [Bundle Size](../../bundle-size.md) | [Performance](../../performance.md) |
| ---------- | ----------------------------------- | ----------------------------------- | | ---------- | ----------------------------------- | ----------------------------------- |
| es-toolkit | 90 bytes (92.4% smaller) | 9,317,227 times (85% faster) | | es-toolkit | 90 bytes (92.4% smaller) | 9,317,227 times (85% faster) |
| lodash-es | 7,958 bytes | 5,030,861 times | | lodash-es | 7,958 bytes | 5,030,861 times |

View File

@ -7,11 +7,7 @@ It works the same as if you called [Array#flat](https://developer.mozilla.org/en
## Signature ## Signature
```typescript ```typescript
function flatMap<T, U, D extends number = 1>( function flatMap<T, U, D extends number = 1>(arr: T[], iteratee: (item: T) => U, depth?: D): Array<FlatArray<U[], D>>;
arr: T[],
iteratee: (item: T) => U,
depth?: D
): Array<FlatArray<U[], D>>;
``` ```
### Parameters ### Parameters

View File

@ -2,7 +2,6 @@
Iterates over elements of `arr` from right to left and invokes `callback` for each element. Iterates over elements of `arr` from right to left and invokes `callback` for each element.
## Signature ## Signature
```ts ```ts
@ -13,9 +12,9 @@ function forEachRight<T>(arr: T[], callback: (value: T, index: number, arr: T[])
- `arr` (`T[]`): The array to iterate over. - `arr` (`T[]`): The array to iterate over.
- `callback` (`(value: T, index: number, arr: T[])`): The function invoked per iteration. - `callback` (`(value: T, index: number, arr: T[])`): The function invoked per iteration.
- `value`: The current element being processed in the array. - `value`: The current element being processed in the array.
- `index`: The index of the current element being processed in the array. - `index`: The index of the current element being processed in the array.
- `arr`: The array `forEachRight` was called upon. - `arr`: The array `forEachRight` was called upon.
### Returns ### Returns
@ -30,9 +29,9 @@ const array = [1, 2, 3];
const result: number[] = []; const result: number[] = [];
// Use the forEachRight function to iterate through the array and add each element to the result array. // Use the forEachRight function to iterate through the array and add each element to the result array.
forEachRight(array, (value) => { forEachRight(array, value => {
result.push(value); result.push(value);
}); });
console.log(result) // Output: [3, 2, 1]; console.log(result); // Output: [3, 2, 1];
``` ```

View File

@ -15,7 +15,7 @@ function unzipWith<T, R>(target: T[][], iteratee: (...args: T[]) => R): R[];
### Returns ### Returns
(`R[]`): A new array of unzipped and transformed elements. (`R[]`): A new array of unzipped and transformed elements.
## Examples ## Examples

View File

@ -5,10 +5,7 @@ Creates a function that invokes func, with up to n arguments, ignoring any addit
## Signature ## Signature
```typescript ```typescript
function ary<F extends (...args: any[]) => any>( function ary<F extends (...args: any[]) => any>(func: F, n: number): (...args: any[]) => ReturnType<F>;
func: F,
n: number
): (...args: any[]) => ReturnType<F>;
``` ```
### Parameters ### Parameters

View File

@ -25,14 +25,14 @@ function flattenObject(object: object): Record<string, any>;
const nestedObject = { const nestedObject = {
a: { a: {
b: { b: {
c: 1 c: 1,
} },
}, },
d: [2, 3] d: [2, 3],
}; };
const flattened = flattenObject(nestedObject); const flattened = flattenObject(nestedObject);
console.log(flattened); console.log(flattened);
// Output: // Output:
// { // {
// 'a.b.c': 1, // 'a.b.c': 1,

View File

@ -1,6 +1,6 @@
# withTimeout # withTimeout
Executes an async function and enforces a timeout. Executes an async function and enforces a timeout.
If the promise does not resolve within the specified time, If the promise does not resolve within the specified time,
the timeout will trigger and the returned promise will be rejected. the timeout will trigger and the returned promise will be rejected.

View File

@ -1,30 +1,30 @@
# kebabCase # kebabCase
Converts a string to kebab case. Converts a string to kebab case.
Kebab case is the naming convention in which each word is written in lowercase and separated by an dash (\-) character. For example, `kebab-case`. Kebab case is the naming convention in which each word is written in lowercase and separated by an dash (\-) character. For example, `kebab-case`.
## Signature ## Signature
```typescript ```typescript
function kebabCase(str: string): string; function kebabCase(str: string): string;
``` ```
### Parameters ### Parameters
- `str` (`string`): The string that is to be changed to kebab case. - `str` (`string`): The string that is to be changed to kebab case.
### Returns ### Returns
(`string`) The converted string to kebab case. (`string`) The converted string to kebab case.
## Examples ## Examples
```typescript ```typescript
import { kebabCase } from 'es-toolkit/string'; import { kebabCase } from 'es-toolkit/string';
kebabCase('camelCase'); // returns 'camel-case' kebabCase('camelCase'); // returns 'camel-case'
kebabCase('some whitespace'); // returns 'some-whitespace' kebabCase('some whitespace'); // returns 'some-whitespace'
kebabCase('hyphen-text'); // returns 'hyphen-text' kebabCase('hyphen-text'); // returns 'hyphen-text'
kebabCase('HTTPRequest'); // returns 'http-request' kebabCase('HTTPRequest'); // returns 'http-request'
``` ```

View File

@ -27,10 +27,10 @@ description: es-toolkit提供的最小包体积
我们的包体积是使用 [esbuild 0.23.0](https://esbuild.github.io) 测量的,通过分析如下代码的大小: 我们的包体积是使用 [esbuild 0.23.0](https://esbuild.github.io) 测量的,通过分析如下代码的大小:
```tsx ```tsx
import { chunk } from 'es-toolkit'; import { chunk } from 'es-toolkit';
// 或 import { chunk } from 'lodash-es'; // 或 import { chunk } from 'lodash-es';
console.log(chunk); console.log(chunk);
``` ```
有关详细信息,请参见我们的[包体积基准代码](https://github.com/toss/es-toolkit/tree/main/benchmarks/bundle-size)。 有关详细信息,请参见我们的[包体积基准代码](https://github.com/toss/es-toolkit/tree/main/benchmarks/bundle-size)。

View File

@ -21,3 +21,4 @@ function compact<T>(arr: T[]): Array<Exclude<T, false | null | 0 | '' | undefine
```typescript ```typescript
compact([0, 1, false, 2, '', 3, null, undefined, 4, NaN, 5]); compact([0, 1, false, 2, '', 3, null, undefined, 4, NaN, 5]);
// 返回: [1, 2, 3, 4, 5] // 返回: [1, 2, 3, 4, 5]
```

View File

@ -1,11 +1,11 @@
# countBy # countBy
根据 `mapper` 函数统计数组中每个项目的出现次数。 根据 `mapper` 函数统计数组中每个项目的出现次数。
## 签名 ## 签名
```typescript ```typescript
function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, number> function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, number>;
``` ```
### 参数 ### 参数
@ -23,7 +23,7 @@ function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, numbe
import { countBy } from 'es-toolkit/array'; import { countBy } from 'es-toolkit/array';
const array = [1, 2, 3, 4, 5, 6]; const array = [1, 2, 3, 4, 5, 6];
const result = countBy(array, x => x % 2 === 0 ? 'even' : 'odd'); const result = countBy(array, x => (x % 2 === 0 ? 'even' : 'odd'));
console.log(result); console.log(result);
// 输出: { 'odd': 3, 'even': 3 } // 输出: { 'odd': 3, 'even': 3 }

View File

@ -7,11 +7,7 @@
## 签名 ## 签名
```typescript ```typescript
function flatMap<T, U, D extends number = 1>( function flatMap<T, U, D extends number = 1>(arr: T[], iteratee: (item: T) => U, depth?: D): Array<FlatArray<U[], D>>;
arr: T[],
iteratee: (item: T) => U,
depth?: D
): Array<FlatArray<U[], D>>;
``` ```
### 参数 ### 参数

View File

@ -29,9 +29,9 @@ const array = [1, 2, 3];
const result: number[] = []; const result: number[] = [];
// 使用 `forEachRight` 函数迭代数组,并将每个元素添加到结果数组中。 // 使用 `forEachRight` 函数迭代数组,并将每个元素添加到结果数组中。
forEachRight(array, (value) => { forEachRight(array, value => {
result.push(value); result.push(value);
}); });
console.log(result) // Output: [3, 2, 1]; console.log(result); // Output: [3, 2, 1];
``` ```

View File

@ -31,3 +31,4 @@ const subset2 = ['a', 'd'];
isSubset(superset2, subset2); isSubset(superset2, subset2);
// 返回 false // 返回 false
```

View File

@ -18,7 +18,7 @@ function randomInt(minimum: number, maximum: number): number;
### 返回值 ### 返回值
- (`number`): 指定范围内的随机整数。 - (`number`): 指定范围内的随机整数。
## 示例 ## 示例

View File

@ -25,18 +25,18 @@ function flattenObject(object: object): Record<string, any>;
const nestedObject = { const nestedObject = {
a: { a: {
b: { b: {
c: 1 c: 1,
} },
}, },
d: [2, 3] d: [2, 3],
}; };
const flattened = flattenObject(nestedObject); const flattened = flattenObject(nestedObject);
console.log(flattened); console.log(flattened);
// 输出: // 输出:
// { // {
// 'a.b.c': 1, // 'a.b.c': 1,
// 'd.0': 2, // 'd.0': 2,
// 'd.1': 3 // 'd.1': 3
// } // }
``` ```

View File

@ -6,8 +6,6 @@
"./compat": "./src/compat/index.ts" "./compat": "./src/compat/index.ts"
}, },
"publish": { "publish": {
"include": [ "include": ["./src/**/*.ts"]
"./src/**/*.ts"
]
} }
} }

View File

@ -170,4 +170,4 @@
"lint": "eslint ./src --ext .ts", "lint": "eslint ./src --ext .ts",
"format": "prettier --write ." "format": "prettier --write ."
} }
} }

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import {countBy} from "./countBy.ts"; import { countBy } from './countBy.ts';
describe('countBy', () => { describe('countBy', () => {
it('should count the occurrences of each item in an array', () => { it('should count the occurrences of each item in an array', () => {
@ -16,11 +16,11 @@ describe('countBy', () => {
}); });
it('should count the occurrences of each item in an array that applied transformer', () => { it('should count the occurrences of each item in an array that applied transformer', () => {
const arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]; const arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
const result = countBy(arr, (item) => item % 2 === 0 ? 'even' : 'odd'); const result = countBy(arr, item => (item % 2 === 0 ? 'even' : 'odd'));
expect(result).toEqual({ expect(result).toEqual({
'odd': 6, odd: 6,
'even': 4, even: 4,
}); });
}) });
}); });

View File

@ -17,12 +17,12 @@
*/ */
export function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, number> { export function countBy<T>(arr: T[], mapper: (item: T) => string): Record<string, number> {
const result: Record<string, number> = {}; const result: Record<string, number> = {};
for (const item of arr) { for (const item of arr) {
const key = mapper(item); const key = mapper(item);
result[key] = (result[key] ?? 0) + 1; result[key] = (result[key] ?? 0) + 1;
} }
return result; return result;
} }

View File

@ -25,5 +25,8 @@ export function flatMap<T, U, D extends number>(
iteratee: (item: T) => U, iteratee: (item: T) => U,
depth = 1 as D depth = 1 as D
): Array<FlatArray<U[], D>> { ): Array<FlatArray<U[], D>> {
return flatten(arr.map(item => iteratee(item)), depth); return flatten(
arr.map(item => iteratee(item)),
depth
);
} }

View File

@ -1,6 +1,6 @@
/** /**
* Iterates over elements of 'arr' from right to left and invokes 'callback' for each element. * Iterates over elements of 'arr' from right to left and invokes 'callback' for each element.
* *
* @template T - The type of elements in the array. * @template T - The type of elements in the array.
* @param {T[]} arr - The array to iterate over. * @param {T[]} arr - The array to iterate over.
* @param {(value: T, index: number, arr: T[]) => void} callback - The function invoked per iteration. * @param {(value: T, index: number, arr: T[]) => void} callback - The function invoked per iteration.
@ -8,16 +8,16 @@
* - 'value': The current element being processed in the array. * - 'value': The current element being processed in the array.
* - 'index': The index of the current element being processed in the array. * - 'index': The index of the current element being processed in the array.
* - 'arr': The array 'forEachRight' was called upon. * - 'arr': The array 'forEachRight' was called upon.
* *
* @example * @example
* const array = [1, 2, 3]; * const array = [1, 2, 3];
* const result: number[] = []; * const result: number[] = [];
* *
* // Use the forEachRight function to iterate through the array and add each element to the result array. * // Use the forEachRight function to iterate through the array and add each element to the result array.
* forEachRight(array, (value) => { * forEachRight(array, (value) => {
* result.push(value); * result.push(value);
* }) * })
* *
* console.log(result) // Output: [3, 2, 1] * console.log(result) // Output: [3, 2, 1]
*/ */

View File

@ -5,7 +5,7 @@
* @param {T[][]} target - The nested array to unzip. This is an array of arrays, * @param {T[][]} target - The nested array to unzip. This is an array of arrays,
* where each inner array contains elements to be unzipped. * where each inner array contains elements to be unzipped.
* @param {(...args: T[]) => R} iteratee - A function to transform the unzipped elements. * @param {(...args: T[]) => R} iteratee - A function to transform the unzipped elements.
* @returns {R[]} A new array of unzipped and transformed elements. * @returns {R[]} A new array of unzipped and transformed elements.
* *
* @example * @example
* const nestedArray = [[1, 2], [3, 4], [5, 6]]; * const nestedArray = [[1, 2], [3, 4], [5, 6]];

View File

@ -1 +1 @@
export const LARGE_ARRAY_SIZE = 200; export const LARGE_ARRAY_SIZE = 200;

View File

@ -1,6 +1,3 @@
import { typedArrays } from "./typedArrays"; import { typedArrays } from './typedArrays';
export const arrayViews = [ export const arrayViews = [...typedArrays, 'DataView'];
...typedArrays,
'DataView'
];

View File

@ -1,3 +1,3 @@
import { falsey } from "./falsey.ts"; import { falsey } from './falsey.ts';
export const empties = [[], {}].concat(falsey.slice(1)); export const empties = [[], {}].concat(falsey.slice(1));

View File

@ -1,4 +1,3 @@
export function getSymbols(object: {}) { export function getSymbols(object: {}) {
return Object.getOwnPropertySymbols(object) return Object.getOwnPropertySymbols(object).filter(symbol => object.propertyIsEnumerable(symbol));
.filter(symbol => object.propertyIsEnumerable(symbol)); }
}

View File

@ -1,3 +1,3 @@
export function identity<T>(x: T) { export function identity<T>(x: T) {
return x; return x;
} }

View File

@ -1,16 +1,16 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { isDeepKey } from "./isDeepKey"; import { isDeepKey } from './isDeepKey';
describe("isDeepKey function", () => { describe('isDeepKey function', () => {
it("returns true for deep keys", () => { it('returns true for deep keys', () => {
expect(isDeepKey("a.b")).toBe(true); expect(isDeepKey('a.b')).toBe(true);
expect(isDeepKey("a[b]")).toBe(true); expect(isDeepKey('a[b]')).toBe(true);
expect(isDeepKey("a.b.c")).toBe(true); expect(isDeepKey('a.b.c')).toBe(true);
expect(isDeepKey("a[b][c]")).toBe(true); expect(isDeepKey('a[b][c]')).toBe(true);
}); });
it("returns false for non-deep keys", () => { it('returns false for non-deep keys', () => {
expect(isDeepKey("a")).toBe(false); expect(isDeepKey('a')).toBe(false);
expect(isDeepKey(123)).toBe(false); expect(isDeepKey(123)).toBe(false);
}); });
}); });

View File

@ -1,4 +1,4 @@
const IS_UNSIGNED_INTEGER = /^(?:0|[1-9]\d*)$/ const IS_UNSIGNED_INTEGER = /^(?:0|[1-9]\d*)$/;
export function isIndex(value: PropertyKey) { export function isIndex(value: PropertyKey) {
switch (typeof value) { switch (typeof value) {
@ -12,4 +12,4 @@ export function isIndex(value: PropertyKey) {
return IS_UNSIGNED_INTEGER.test(value); return IS_UNSIGNED_INTEGER.test(value);
} }
} }
} }

View File

@ -1 +1 @@
export const numberProto: any = Number.prototype; export const numberProto: any = Number.prototype;

View File

@ -12,7 +12,7 @@ export const functionTag = '[object Function]';
export const arrayBufferTag = '[object ArrayBuffer]'; export const arrayBufferTag = '[object ArrayBuffer]';
export const objectTag = '[object Object]'; export const objectTag = '[object Object]';
export const errorTag = '[object Error]'; export const errorTag = '[object Error]';
export const dataViewTag = '[object DataView]' export const dataViewTag = '[object DataView]';
export const uint8ArrayTag = '[object Uint8Array]'; export const uint8ArrayTag = '[object Uint8Array]';
export const uint8ClampedArrayTag = '[object Uint8ClampedArray]'; export const uint8ClampedArrayTag = '[object Uint8ClampedArray]';
export const uint16ArrayTag = '[object Uint16Array]'; export const uint16ArrayTag = '[object Uint16Array]';
@ -23,4 +23,4 @@ export const int16ArrayTag = '[object Int16Array]';
export const int32ArrayTag = '[object Int32Array]'; export const int32ArrayTag = '[object Int32Array]';
export const bigInt64ArrayTag = '[object BigInt64Array]'; export const bigInt64ArrayTag = '[object BigInt64Array]';
export const float32ArrayTag = '[object Float32Array]'; export const float32ArrayTag = '[object Float32Array]';
export const float64ArrayTag = '[object Float64Array]'; export const float64ArrayTag = '[object Float64Array]';

View File

@ -1,49 +1,49 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { toPath } from "./toPath"; import { toPath } from './toPath';
describe("toPath function", () => { describe('toPath function', () => {
it("converts dot-separated keys correctly", () => { it('converts dot-separated keys correctly', () => {
const result = toPath("a.b.c"); const result = toPath('a.b.c');
expect(result).toEqual(["a", "b", "c"]); expect(result).toEqual(['a', 'b', 'c']);
}); });
it("converts bracket notation keys correctly", () => { it('converts bracket notation keys correctly', () => {
const result = toPath("a[b][c]"); const result = toPath('a[b][c]');
expect(result).toEqual(["a", "b", "c"]); expect(result).toEqual(['a', 'b', 'c']);
}); });
it("handles mixed notation correctly", () => { it('handles mixed notation correctly', () => {
const result = toPath("a[b].c"); const result = toPath('a[b].c');
expect(result).toEqual(["a", "b", "c"]); expect(result).toEqual(['a', 'b', 'c']);
}); });
it("handles leading dots correctly", () => { it('handles leading dots correctly', () => {
const result = toPath(".a.b.c"); const result = toPath('.a.b.c');
expect(result).toEqual(["", "a", "b", "c"]); expect(result).toEqual(['', 'a', 'b', 'c']);
}); });
it("handles quoted keys correctly", () => { it('handles quoted keys correctly', () => {
const result = toPath('a["b.c"].d'); const result = toPath('a["b.c"].d');
expect(result).toEqual(["a", "b.c", "d"]); expect(result).toEqual(['a', 'b.c', 'd']);
}); });
it("handles empty input correctly", () => { it('handles empty input correctly', () => {
const result = toPath(""); const result = toPath('');
expect(result).toEqual([]); expect(result).toEqual([]);
}); });
it("handles complex paths correctly", () => { it('handles complex paths correctly', () => {
const result = toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g'); const result = toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
expect(result).toEqual(['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']); expect(result).toEqual(['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
}); });
it("handles complex input with leading dot correctly", () => { it('handles complex input with leading dot correctly', () => {
const result = toPath('.a[b].c.d[e]["f.g"].h'); const result = toPath('.a[b].c.d[e]["f.g"].h');
expect(result).toEqual(["", "a", "b", "c", "d", "e", "f.g", "h"]); expect(result).toEqual(['', 'a', 'b', 'c', 'd', 'e', 'f.g', 'h']);
}); });
it("handles empty brackets correctly", () => { it('handles empty brackets correctly', () => {
const result = toPath("a[].b"); const result = toPath('a[].b');
expect(result).toEqual(['a', '', 'b']); expect(result).toEqual(['a', '', 'b']);
}); });
}); });

View File

@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { compact } from "../../array/compact"; import { compact } from '../../array/compact';
import { falsey } from "../_internal/falsey"; import { falsey } from '../_internal/falsey';
/** /**
* @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/compact.spec.js#L1 * @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/compact.spec.js#L1

View File

@ -1,13 +1,12 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { difference } from "./difference"; import { difference } from './difference';
import { LARGE_ARRAY_SIZE } from "../_internal/LARGE_ARRAY_SIZE"; import { LARGE_ARRAY_SIZE } from '../_internal/LARGE_ARRAY_SIZE';
import { range } from "../../math/range"; import { range } from '../../math/range';
/** /**
* @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/difference-methods.spec.js#L1 * @see https://github.com/lodash/lodash/blob/6a2cc1dfcf7634fea70d1bc5bd22db453df67b42/test/difference-methods.spec.js#L1
*/ */
describe('difference', () => { describe('difference', () => {
it(`should return the difference of two arrays`, () => { it(`should return the difference of two arrays`, () => {
const actual = difference([2, 1], [2, 3]); const actual = difference([2, 1], [2, 3]);
expect(actual).toEqual([1]); expect(actual).toEqual([1]);
@ -21,7 +20,7 @@ describe('difference', () => {
it(`should treat \`-0\` as \`0\``, () => { it(`should treat \`-0\` as \`0\``, () => {
const array = [-0, 0]; const array = [-0, 0];
const actual = array.map((value) => difference(array, [value])); const actual = array.map(value => difference(array, [value]));
expect(actual).toEqual([[], []]); expect(actual).toEqual([[], []]);
@ -49,7 +48,7 @@ describe('difference', () => {
it(`should work with large arrays of \`-0\` as \`0\``, () => { it(`should work with large arrays of \`-0\` as \`0\``, () => {
const array = [-0, 0]; const array = [-0, 0];
const actual = array.map((value) => { const actual = array.map(value => {
const largeArray = Array.from({ length: LARGE_ARRAY_SIZE }).map(() => value); const largeArray = Array.from({ length: LARGE_ARRAY_SIZE }).map(() => value);
return difference(array, largeArray); return difference(array, largeArray);

View File

@ -6,4 +6,4 @@ export function difference<T>(arr: readonly T[], ...values: Array<readonly T[]>)
const arr2 = flatten(values); const arr2 = flatten(values);
return differenceToolkit(arr1, arr2); return differenceToolkit(arr1, arr2);
} }

View File

@ -1,5 +1,5 @@
import { zip } from "../../array/zip.ts"; import { zip } from '../../array/zip.ts';
import { set } from "../object/set.ts"; import { set } from '../object/set.ts';
/** /**
* Creates a deeply nested object given arrays of paths and values. * Creates a deeply nested object given arrays of paths and values.
@ -7,7 +7,7 @@ import { set } from "../object/set.ts";
* This function takes two arrays: one containing arrays of property paths, and the other containing corresponding values. * This function takes two arrays: one containing arrays of property paths, and the other containing corresponding values.
* It returns a new object where paths from the first array are used as key paths to set values, with corresponding elements from the second array as values. * It returns a new object where paths from the first array are used as key paths to set values, with corresponding elements from the second array as values.
* Paths can be dot-separated strings or arrays of property names. * Paths can be dot-separated strings or arrays of property names.
* *
* If the `keys` array is longer than the `values` array, the remaining keys will have `undefined` as their values. * If the `keys` array is longer than the `values` array, the remaining keys will have `undefined` as their values.
* *
* @template V - The type of elements in the array. * @template V - The type of elements in the array.
@ -26,7 +26,7 @@ import { set } from "../object/set.ts";
* const values = [1, 2]; * const values = [1, 2];
* const result = zipObjectDeep(paths, values); * const result = zipObjectDeep(paths, values);
* // result will be { a: { b: { c: 1 } }, d: { e: { f: 2 } } } * // result will be { a: { b: { c: 1 } }, d: { e: { f: 2 } } }
* *
* @example * @example
* const paths = ['a.b[0].c', 'a.b[1].d']; * const paths = ['a.b[0].c', 'a.b[1].d'];
* const values = [1, 2]; * const values = [1, 2];

View File

@ -8,7 +8,11 @@ import { ary as aryToolkit } from '../../function/ary.ts';
* @param {number} n - The arity cap. * @param {number} n - The arity cap.
* @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function. * @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function.
*/ */
export function ary<F extends (...args: any[]) => any>(func: F, n: number = func.length, guard?: unknown): ((...args: any[]) => ReturnType<F>) { export function ary<F extends (...args: any[]) => any>(
func: F,
n: number = func.length,
guard?: unknown
): (...args: any[]) => ReturnType<F> {
if (guard) { if (guard) {
n = func.length; n = func.length;
} }
@ -18,4 +22,4 @@ export function ary<F extends (...args: any[]) => any>(func: F, n: number = func
} }
return aryToolkit(func, n); return aryToolkit(func, n);
}; }

View File

@ -79,7 +79,7 @@ describe('bind', () => {
it('should create a function with a `length` of `0`', () => { it('should create a function with a `length` of `0`', () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const fn = function (_a: unknown, _b: unknown, _c: unknown) { }; const fn = function (_a: unknown, _b: unknown, _c: unknown) {};
let bound = bind(fn, {}); let bound = bind(fn, {});
expect(bound.length).toBe(0); expect(bound.length).toBe(0);
@ -107,7 +107,7 @@ describe('bind', () => {
return this; return this;
} }
function Bar() { } function Bar() {}
const thisArg = { a: 1 }; const thisArg = { a: 1 };
const boundFoo = bind(Foo, thisArg) as any; const boundFoo = bind(Foo, thisArg) as any;
@ -173,7 +173,7 @@ describe('bind', () => {
it('should not error when calling bound class constructors with the `new` operator', () => { it('should not error when calling bound class constructors with the `new` operator', () => {
const createCtor: any = function () { const createCtor: any = function () {
return class A { }; return class A {};
}; };
const bound = bind(createCtor()) as any; const bound = bind(createCtor()) as any;

View File

@ -58,4 +58,4 @@ export function bind<F extends Function>(func: F, thisObj?: unknown, ...partialA
} }
const bindPlaceholder: unique symbol = Symbol('bind.placeholder'); const bindPlaceholder: unique symbol = Symbol('bind.placeholder');
bind.placeholder = bindPlaceholder; bind.placeholder = bindPlaceholder;

View File

@ -1,6 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { min } from "./min"; import { min } from './min';
describe('min', () => { describe('min', () => {
it('should return the largest value from a collection', () => { it('should return the largest value from a collection', () => {

View File

@ -78,9 +78,8 @@ export function cloneDeep<T>(obj: T): T {
return result as T; return result as T;
} }
default: { default: {
return cloneDeepToolkit(obj); return cloneDeepToolkit(obj);
} }
} }
} }

View File

@ -1,14 +1,14 @@
import { isDeepKey } from "../_internal/isDeepKey.ts"; import { isDeepKey } from '../_internal/isDeepKey.ts';
import { toPath } from "../_internal/toPath.ts"; import { toPath } from '../_internal/toPath.ts';
import type { Get } from "./get.types.ts"; import type { Get } from './get.types.ts';
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K - The type of the key in the object. * @template K - The type of the key in the object.
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {T} object - The object to query. * @param {T} object - The object to query.
* @param {K | [K]} path - The path of the property to get. * @param {K | [K]} path - The path of the property to get.
* @returns {T[K]} - Returns the resolved value. * @returns {T[K]} - Returns the resolved value.
@ -16,10 +16,10 @@ import type { Get } from "./get.types.ts";
export function get<T extends object, K extends keyof T>(object: T, path: K | [K]): T[K]; export function get<T extends object, K extends keyof T>(object: T, path: K | [K]): T[K];
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K - The type of the key in the object. * @template K - The type of the key in the object.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {K | [K]} path - The path of the property to get. * @param {K | [K]} path - The path of the property to get.
* @returns {T[K] | undefined} - Returns the resolved value. * @returns {T[K] | undefined} - Returns the resolved value.
@ -27,24 +27,28 @@ export function get<T extends object, K extends keyof T>(object: T, path: K | [K
export function get<T extends object, K extends keyof T>(object: T | null | undefined, path: K | [K]): T[K] | undefined; export function get<T extends object, K extends keyof T>(object: T | null | undefined, path: K | [K]): T[K] | undefined;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K - The type of the key in the object. * @template K - The type of the key in the object.
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {K | [K]} path - The path of the property to get. * @param {K | [K]} path - The path of the property to get.
* @param {D} defaultValue - The value returned if the resolved value is undefined. * @param {D} defaultValue - The value returned if the resolved value is undefined.
* @returns {Exclude<T[K], undefined> | D} - Returns the resolved value. * @returns {Exclude<T[K], undefined> | D} - Returns the resolved value.
*/ */
export function get<T extends object, K extends keyof T, D>(object: T | null | undefined, path: K | [K], defaultValue: D): Exclude<T[K], undefined> | D; export function get<T extends object, K extends keyof T, D>(
object: T | null | undefined,
path: K | [K],
defaultValue: D
): Exclude<T[K], undefined> | D;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* *
* @param {T} object - The object to query. * @param {T} object - The object to query.
* @param {[K1, K2]} path - The path of the property to get. * @param {[K1, K2]} path - The path of the property to get.
* @returns {T[K1][K2]} - Returns the resolved value. * @returns {T[K1][K2]} - Returns the resolved value.
@ -52,120 +56,156 @@ export function get<T extends object, K extends keyof T, D>(object: T | null | u
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, path: [K1, K2]): T[K1][K2]; export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, path: [K1, K2]): T[K1][K2];
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {[K1, K2]} path - The path of the property to get. * @param {[K1, K2]} path - The path of the property to get.
* @returns {T[K1][K2] | undefined} - Returns the resolved value. * @returns {T[K1][K2] | undefined} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1]>(object: T | null | undefined, path: [K1, K2]): T[K1][K2] | undefined; export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1]>(
object: T | null | undefined,
path: [K1, K2]
): T[K1][K2] | undefined;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {[K1, K2]} path - The path of the property to get. * @param {[K1, K2]} path - The path of the property to get.
* @param {D} defaultValue - The value returned if the resolved value is undefined. * @param {D} defaultValue - The value returned if the resolved value is undefined.
* @returns {Exclude<T[K1][K2], undefined> | D} - Returns the resolved value. * @returns {Exclude<T[K1][K2], undefined> | D} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], D>(object: T | null | undefined, path: [K1, K2], defaultValue: D): Exclude<T[K1][K2], undefined> | D; export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], D>(
object: T | null | undefined,
path: [K1, K2],
defaultValue: D
): Exclude<T[K1][K2], undefined> | D;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* @template K3 - The type of the third key in the object. * @template K3 - The type of the third key in the object.
* *
* @param {T} object - The object to query. * @param {T} object - The object to query.
* @param {[K1, K2, K3]} path - The path of the property to get. * @param {[K1, K2, K3]} path - The path of the property to get.
* @returns {T[K1][K2][K3]} - Returns the resolved value. * @returns {T[K1][K2][K3]} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(object: T, path: [K1, K2, K3]): T[K1][K2][K3]; export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(
object: T,
path: [K1, K2, K3]
): T[K1][K2][K3];
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* @template K3 - The type of the third key in the object. * @template K3 - The type of the third key in the object.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {[K1, K2, K3]} path - The path of the property to get. * @param {[K1, K2, K3]} path - The path of the property to get.
* @returns {T[K1][K2][K3] | undefined} - Returns the resolved value. * @returns {T[K1][K2][K3] | undefined} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(object: T | null | undefined, path: [K1, K2, K3]): T[K1][K2][K3] | undefined; export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(
object: T | null | undefined,
path: [K1, K2, K3]
): T[K1][K2][K3] | undefined;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* @template K3 - The type of the third key in the object. * @template K3 - The type of the third key in the object.
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {[K1, K2, K3]} path - The path of the property to get. * @param {[K1, K2, K3]} path - The path of the property to get.
* @param {D} defaultValue - The value returned if the resolved value is undefined. * @param {D} defaultValue - The value returned if the resolved value is undefined.
* @returns {Exclude<T[K1][K2][K3], undefined> | D} - Returns the resolved value. * @returns {Exclude<T[K1][K2][K3], undefined> | D} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], D>(object: T | null | undefined, path: [K1, K2, K3], defaultValue: D): Exclude<T[K1][K2][K3], undefined> | D; export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], D>(
object: T | null | undefined,
path: [K1, K2, K3],
defaultValue: D
): Exclude<T[K1][K2][K3], undefined> | D;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* @template K3 - The type of the third key in the object. * @template K3 - The type of the third key in the object.
* @template K4 - The type of the fourth key in the object. * @template K4 - The type of the fourth key in the object.
* *
* @param {T} object - The object to query. * @param {T} object - The object to query.
* @param {[K1, K2, K3, K4]} path - The path of the property to get. * @param {[K1, K2, K3, K4]} path - The path of the property to get.
* @returns {T[K1][K2][K3][K4]} - Returns the resolved value. * @returns {T[K1][K2][K3][K4]} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3]>(object: T, path: [K1, K2, K3, K4]): T[K1][K2][K3][K4]; export function get<
T extends object,
K1 extends keyof T,
K2 extends keyof T[K1],
K3 extends keyof T[K1][K2],
K4 extends keyof T[K1][K2][K3],
>(object: T, path: [K1, K2, K3, K4]): T[K1][K2][K3][K4];
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* @template K3 - The type of the third key in the object. * @template K3 - The type of the third key in the object.
* @template K4 - The type of the fourth key in the object. * @template K4 - The type of the fourth key in the object.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {[K1, K2, K3, K4]} path - The path of the property to get. * @param {[K1, K2, K3, K4]} path - The path of the property to get.
* @returns {T[K1][K2][K3][K4] | undefined} - Returns the resolved value. * @returns {T[K1][K2][K3][K4] | undefined} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3]>(object: T | null | undefined, path: [K1, K2, K3, K4]): T[K1][K2][K3][K4] | undefined; export function get<
T extends object,
K1 extends keyof T,
K2 extends keyof T[K1],
K3 extends keyof T[K1][K2],
K4 extends keyof T[K1][K2][K3],
>(object: T | null | undefined, path: [K1, K2, K3, K4]): T[K1][K2][K3][K4] | undefined;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template K1 - The type of the first key in the object. * @template K1 - The type of the first key in the object.
* @template K2 - The type of the second key in the object. * @template K2 - The type of the second key in the object.
* @template K3 - The type of the third key in the object. * @template K3 - The type of the third key in the object.
* @template K4 - The type of the fourth key in the object. * @template K4 - The type of the fourth key in the object.
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {T | null | undefined} object - The object to query. * @param {T | null | undefined} object - The object to query.
* @param {[K1, K2, K3, K4]} path - The path of the property to get. * @param {[K1, K2, K3, K4]} path - The path of the property to get.
* @param {D} defaultValue - The value returned if the resolved value is undefined. * @param {D} defaultValue - The value returned if the resolved value is undefined.
* @returns {Exclude<T[K1][K2][K3][K4], undefined> | D} - Returns the resolved value. * @returns {Exclude<T[K1][K2][K3][K4], undefined> | D} - Returns the resolved value.
*/ */
export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3], D>(object: T | null | undefined, path: [K1, K2, K3, K4], defaultValue: D): Exclude<T[K1][K2][K3][K4], undefined> | D; export function get<
T extends object,
K1 extends keyof T,
K2 extends keyof T[K1],
K3 extends keyof T[K1][K2],
K4 extends keyof T[K1][K2][K3],
D,
>(object: T | null | undefined, path: [K1, K2, K3, K4], defaultValue: D): Exclude<T[K1][K2][K3][K4], undefined> | D;
/** /**
* Retrieves the value at a given path from an object with numeric keys. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object with numeric keys. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the value. * @template T - The type of the value.
* *
* @param {Record<number, T>} object - The object to query. * @param {Record<number, T>} object - The object to query.
* @param {number} path - The path of the property to get. * @param {number} path - The path of the property to get.
* @returns {T} - Returns the resolved value. * @returns {T} - Returns the resolved value.
@ -173,9 +213,9 @@ export function get<T extends object, K1 extends keyof T, K2 extends keyof T[K1]
export function get<T>(object: Record<number, T>, path: number): T; export function get<T>(object: Record<number, T>, path: number): T;
/** /**
* Retrieves the value at a given path from an object with numeric keys. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object with numeric keys. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the value. * @template T - The type of the value.
* *
* @param {Record<number, T> | null | undefined} object - The object to query. * @param {Record<number, T> | null | undefined} object - The object to query.
* @param {number} path - The path of the property to get. * @param {number} path - The path of the property to get.
* @returns {T | undefined} - Returns the resolved value. * @returns {T | undefined} - Returns the resolved value.
@ -183,10 +223,10 @@ export function get<T>(object: Record<number, T>, path: number): T;
export function get<T>(object: Record<number, T> | null | undefined, path: number): T | undefined; export function get<T>(object: Record<number, T> | null | undefined, path: number): T | undefined;
/** /**
* Retrieves the value at a given path from an object with numeric keys. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object with numeric keys. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the value. * @template T - The type of the value.
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {Record<number, T> | null | undefined} object - The object to query. * @param {Record<number, T> | null | undefined} object - The object to query.
* @param {number} path - The path of the property to get. * @param {number} path - The path of the property to get.
* @param {D} defaultValue - The value returned if the resolved value is undefined. * @param {D} defaultValue - The value returned if the resolved value is undefined.
@ -195,9 +235,9 @@ export function get<T>(object: Record<number, T> | null | undefined, path: numbe
export function get<T, D>(object: Record<number, T> | null | undefined, path: number, defaultValue: D): T | D; export function get<T, D>(object: Record<number, T> | null | undefined, path: number, defaultValue: D): T | D;
/** /**
* Retrieves the value at a given path from a null or undefined object, returning the default value. * Retrieves the value at a given path from a null or undefined object, returning the default value.
* *
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {null | undefined} object - The object to query. * @param {null | undefined} object - The object to query.
* @param {PropertyKey} path - The path of the property to get. * @param {PropertyKey} path - The path of the property to get.
* @param {D} defaultValue - The value returned if the resolved value is undefined. * @param {D} defaultValue - The value returned if the resolved value is undefined.
@ -206,7 +246,7 @@ export function get<T, D>(object: Record<number, T> | null | undefined, path: nu
export function get<D>(object: null | undefined, path: PropertyKey, defaultValue: D): D; export function get<D>(object: null | undefined, path: PropertyKey, defaultValue: D): D;
/** /**
* Retrieves the value at a given path from a null or undefined object, returning undefined. * Retrieves the value at a given path from a null or undefined object, returning undefined.
* *
* @param {null | undefined} object - The object to query. * @param {null | undefined} object - The object to query.
* @param {PropertyKey} path - The path of the property to get. * @param {PropertyKey} path - The path of the property to get.
* @returns {undefined} - Returns undefined. * @returns {undefined} - Returns undefined.
@ -214,10 +254,10 @@ export function get<D>(object: null | undefined, path: PropertyKey, defaultValue
export function get(object: null | undefined, path: PropertyKey): undefined; export function get(object: null | undefined, path: PropertyKey): undefined;
/** /**
* Retrieves the value at a given path from a string-keyed object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from a string-keyed object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template P - The type of the path. * @template P - The type of the path.
* *
* @param {T} data - The object to query. * @param {T} data - The object to query.
* @param {P} path - The path of the property to get. * @param {P} path - The path of the property to get.
* @returns {string extends P ? any : Get<T, P>} - Returns the resolved value. * @returns {string extends P ? any : Get<T, P>} - Returns the resolved value.
@ -225,20 +265,24 @@ export function get(object: null | undefined, path: PropertyKey): undefined;
export function get<T, P extends string>(data: T, path: P): string extends P ? any : Get<T, P>; export function get<T, P extends string>(data: T, path: P): string extends P ? any : Get<T, P>;
/** /**
* Retrieves the value at a given path from a string-keyed object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from a string-keyed object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @template T - The type of the object. * @template T - The type of the object.
* @template P - The type of the path. * @template P - The type of the path.
* @template D - The type of the default value. * @template D - The type of the default value.
* *
* @param {T} data - The object to query. * @param {T} data - The object to query.
* @param {P} path - The path of the property to get. * @param {P} path - The path of the property to get.
* @param {D} defaultValue - The value returned if the resolved value is undefined. * @param {D} defaultValue - The value returned if the resolved value is undefined.
* @returns {Exclude<Get<T, P>, null | undefined> | D} - Returns the resolved value. * @returns {Exclude<Get<T, P>, null | undefined> | D} - Returns the resolved value.
*/ */
export function get<T, P extends string, D = Get<T, P>>(data: T, path: P, defaultValue: D): Exclude<Get<T, P>, null | undefined> | D; export function get<T, P extends string, D = Get<T, P>>(
data: T,
path: P,
defaultValue: D
): Exclude<Get<T, P>, null | undefined> | D;
/** /**
* Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead. * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.
* *
* @param {unknown} object - The object to query. * @param {unknown} object - The object to query.
* @param {PropertyKey | readonly PropertyKey[]} path - The path of the property to get. * @param {PropertyKey | readonly PropertyKey[]} path - The path of the property to get.
* @param {unknown} [defaultValue] - The value returned if the resolved value is undefined. * @param {unknown} [defaultValue] - The value returned if the resolved value is undefined.
@ -278,4 +322,4 @@ export function get(object: any, path: PropertyKey | readonly PropertyKey[], def
} }
return current ?? defaultValue; return current ?? defaultValue;
} }

View File

@ -4,35 +4,31 @@
type GetIndexedField<T, K> = K extends keyof T type GetIndexedField<T, K> = K extends keyof T
? T[K] ? T[K]
: K extends `${number}` : K extends `${number}`
? 'length' extends keyof T ? 'length' extends keyof T
? number extends T['length'] ? number extends T['length']
? number extends keyof T ? number extends keyof T
? T[number] ? T[number]
: undefined : undefined
: undefined : undefined
: undefined : undefined
: undefined; : undefined;
type FieldWithPossiblyUndefined<T, Key> = type FieldWithPossiblyUndefined<T, Key> = Get<Exclude<T, undefined>, Key> | Extract<T, undefined>;
| Get<Exclude<T, undefined>, Key>
| Extract<T, undefined>;
type IndexedFieldWithPossiblyUndefined<T, Key> = type IndexedFieldWithPossiblyUndefined<T, Key> = GetIndexedField<Exclude<T, undefined>, Key> | Extract<T, undefined>;
| GetIndexedField<Exclude<T, undefined>, Key>
| Extract<T, undefined>;
export type Get<T, P> = P extends `${infer Left}.${infer Right}` export type Get<T, P> = P extends `${infer Left}.${infer Right}`
? Left extends keyof Exclude<T, undefined> ? Left extends keyof Exclude<T, undefined>
? FieldWithPossiblyUndefined<Exclude<T, undefined>[Left], Right> | Extract<T, undefined> ? FieldWithPossiblyUndefined<Exclude<T, undefined>[Left], Right> | Extract<T, undefined>
: Left extends `${infer FieldKey}[${infer IndexKey}]` : Left extends `${infer FieldKey}[${infer IndexKey}]`
? FieldKey extends keyof T ? FieldKey extends keyof T
? FieldWithPossiblyUndefined<IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey>, Right> ? FieldWithPossiblyUndefined<IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey>, Right>
: undefined : undefined
: undefined : undefined
: P extends keyof T : P extends keyof T
? T[P] ? T[P]
: P extends `${infer FieldKey}[${infer IndexKey}]` : P extends `${infer FieldKey}[${infer IndexKey}]`
? FieldKey extends keyof T ? FieldKey extends keyof T
? IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey> ? IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey>
: undefined : undefined
: IndexedFieldWithPossiblyUndefined<T, P>; : IndexedFieldWithPossiblyUndefined<T, P>;

View File

@ -1,4 +1,3 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { mapValues } from './mapValues'; import { mapValues } from './mapValues';
import { isEqual } from '../../predicate/isEqual'; import { isEqual } from '../../predicate/isEqual';
@ -7,7 +6,6 @@ describe('mapValues', () => {
const array = [1, 2]; const array = [1, 2];
const object = { a: 1, b: 2 }; const object = { a: 1, b: 2 };
it('should map values in `object` to a new object', () => { it('should map values in `object` to a new object', () => {
const actual = mapValues(object, String); const actual = mapValues(object, String);
expect(actual).toEqual({ a: '1', b: '2' }); expect(actual).toEqual({ a: '1', b: '2' });

View File

@ -1,4 +1,4 @@
import { get } from "./get.ts"; import { get } from './get.ts';
/** /**
* Creates a function that returns the value at a given path of an object. * Creates a function that returns the value at a given path of an object.
@ -10,7 +10,7 @@ import { get } from "./get.ts";
* const getObjectValue = property('a.b.c'); * const getObjectValue = property('a.b.c');
* const result = getObjectValue({ a: { b: { c: 3 } } }); * const result = getObjectValue({ a: { b: { c: 3 } } });
* console.log(result); // => 3 * console.log(result); // => 3
* *
* @example * @example
* const getObjectValue = property(['a', 'b', 'c']); * const getObjectValue = property(['a', 'b', 'c']);
* const result = getObjectValue({ a: { b: { c: 3 } } }); * const result = getObjectValue({ a: { b: { c: 3 } } });
@ -19,5 +19,5 @@ import { get } from "./get.ts";
export function property(path: PropertyKey | readonly PropertyKey[]): (object: unknown) => any { export function property(path: PropertyKey | readonly PropertyKey[]): (object: unknown) => any {
return function (object: unknown) { return function (object: unknown) {
return get(object, path); return get(object, path);
} };
} }

View File

@ -1,5 +1,5 @@
import { isIndex } from "../_internal/isIndex.ts"; import { isIndex } from '../_internal/isIndex.ts';
import { toPath } from "../_internal/toPath.ts"; import { toPath } from '../_internal/toPath.ts';
/** /**
* Sets the value at the specified path of the given object. If any part of the path does not exist, it will be created. * Sets the value at the specified path of the given object. If any part of the path does not exist, it will be created.
@ -30,11 +30,7 @@ import { toPath } from "../_internal/toPath.ts";
*/ */
export function set<T>(obj: object, path: PropertyKey | readonly PropertyKey[], value: unknown): T; export function set<T>(obj: object, path: PropertyKey | readonly PropertyKey[], value: unknown): T;
export function set<T extends object>(obj: T, path: PropertyKey | readonly PropertyKey[], value: unknown): T { export function set<T extends object>(obj: T, path: PropertyKey | readonly PropertyKey[], value: unknown): T {
const resolvedPath = Array.isArray(path) const resolvedPath = Array.isArray(path) ? path : typeof path === 'string' ? toPath(path) : [path];
? path
: typeof path === 'string'
? toPath(path)
: [path];
let current: any = obj; let current: any = obj;

View File

@ -10,16 +10,16 @@ describe('isArray', function () {
it('returns false if value is not an array', () => { it('returns false if value is not an array', () => {
expect(isArray('abc')).toBe(false); expect(isArray('abc')).toBe(false);
expect(isArray(() => { })).toBe(false); expect(isArray(() => {})).toBe(false);
}); });
it('can be used with TypeScript as a type predicate', () => { it('can be used with TypeScript as a type predicate', () => {
const arr1 = ['abc', () => { }, [1, 2, 3]]; const arr1 = ['abc', () => {}, [1, 2, 3]];
const result1 = arr1.filter(isArray); const result1 = arr1.filter(isArray);
expect(result1).toStrictEqual([[1, 2, 3]]); expect(result1).toStrictEqual([[1, 2, 3]]);
expectTypeOf(result1).toEqualTypeOf<any[][]>(); expectTypeOf(result1).toEqualTypeOf<any[][]>();
const arr2 = ['abc', () => { }, [1, 2, 3] as const]; const arr2 = ['abc', () => {}, [1, 2, 3] as const];
const result2 = arr2.filter(isArray); const result2 = arr2.filter(isArray);
expect(result2).toStrictEqual([[1, 2, 3]]); expect(result2).toStrictEqual([[1, 2, 3]]);
}); });

View File

@ -20,8 +20,8 @@ describe('isArrayLike', () => {
expect(actual).toEqual(expected); expect(actual).toEqual(expected);
const slice = Array.prototype.slice; const slice = Array.prototype.slice;
const asyncFunc = async function () { }; const asyncFunc = async function () {};
const genFunc = function* () { }; const genFunc = function* () {};
const symbol = Symbol ? Symbol('a') : undefined; const symbol = Symbol ? Symbol('a') : undefined;
expect(isArrayLike(true)).toBe(false); expect(isArrayLike(true)).toBe(false);

View File

@ -1,4 +1,4 @@
import { isLength } from "../../predicate/isLength.ts"; import { isLength } from '../../predicate/isLength.ts';
/** /**
* Checks if `value` is array-like. * Checks if `value` is array-like.
@ -15,6 +15,5 @@ import { isLength } from "../../predicate/isLength.ts";
* isArrayLike(undefined); // false * isArrayLike(undefined); // false
*/ */
export function isArrayLike(value: unknown): value is ArrayLike<unknown> { export function isArrayLike(value: unknown): value is ArrayLike<unknown> {
return value != null && typeof value !== "function" && return value != null && typeof value !== 'function' && isLength((value as ArrayLike<unknown>).length);
isLength((value as ArrayLike<unknown>).length);
} }

View File

@ -14,7 +14,7 @@ describe('isBoolean', () => {
}); });
it('should return `false` for non-booleans', () => { it('should return `false` for non-booleans', () => {
const expected = falsey.map((value) => value === false); const expected = falsey.map(value => value === false);
const actual = falsey.map((value, index) => isBoolean(value)); const actual = falsey.map((value, index) => isBoolean(value));

View File

@ -1,5 +1,4 @@
import { getTag } from "../_internal/getTag.ts"; import { getTag } from '../_internal/getTag.ts';
/** /**
* Checks if the given value is boolean. * Checks if the given value is boolean.

View File

@ -1,9 +1,9 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { noop } from "../../function/noop"; import { noop } from '../../function/noop';
import { stubFalse } from "../_internal/stubFalse"; import { stubFalse } from '../_internal/stubFalse';
import { isEqual } from "es-toolkit/compat"; import { isEqual } from 'es-toolkit/compat';
import { args } from "../_internal/args"; import { args } from '../_internal/args';
import { arrayViews } from "../_internal/arrayViews"; import { arrayViews } from '../_internal/arrayViews';
describe('isEqual', () => { describe('isEqual', () => {
const symbol1 = Symbol ? Symbol('a') : true; const symbol1 = Symbol ? Symbol('a') : true;
@ -55,9 +55,9 @@ describe('isEqual', () => {
[undefined, '', false], [undefined, '', false],
]; ];
const expected = pairs.map((pair) => pair[2]); const expected = pairs.map(pair => pair[2]);
const actual = pairs.map((pair) => isEqual(pair[0], pair[1])); const actual = pairs.map(pair => isEqual(pair[0], pair[1]));
expect(actual).toEqual(expected); expect(actual).toEqual(expected);
}); });
@ -82,24 +82,8 @@ describe('isEqual', () => {
expect(isEqual(array1, array2)).toBe(true); expect(isEqual(array1, array2)).toBe(true);
array1 = [ array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { a: 1 }];
Object(1), array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { a: 1 }];
false,
Object('a'),
/x/,
new Date(2012, 4, 23),
['a', 'b', [Object('c')]],
{ a: 1 },
];
array2 = [
1,
Object(false),
'a',
/x/,
new Date(2012, 4, 23),
['a', Object('b'), ['c']],
{ a: 1 },
];
expect(isEqual(array1, array2)).toBe(true); expect(isEqual(array1, array2)).toBe(true);
@ -127,7 +111,7 @@ describe('isEqual', () => {
array1.some = array1.some =
array1.reduce = array1.reduce =
array1.reduceRight = array1.reduceRight =
null; null;
array2.concat = array2.concat =
array2.join = array2.join =
@ -138,7 +122,7 @@ describe('isEqual', () => {
array2.sort = array2.sort =
array2.splice = array2.splice =
array2.unshift = array2.unshift =
null; null;
expect(isEqual(array1, array2)).toBe(true); expect(isEqual(array1, array2)).toBe(true);
@ -447,7 +431,7 @@ describe('isEqual', () => {
it('should treat `arguments` objects like `Object` objects', () => { it('should treat `arguments` objects like `Object` objects', () => {
const object = { 0: 1, 1: 2, 2: 3 }; const object = { 0: 1, 1: 2, 2: 3 };
function Foo() { } function Foo() {}
Foo.prototype = object; Foo.prototype = object;
expect(isEqual(args, object)).toBe(true); expect(isEqual(args, object)).toBe(true);
@ -502,21 +486,12 @@ describe('isEqual', () => {
// @ts-ignore // @ts-ignore
const bufferC = globalThis[otherType] ? new ArrayBuffer(16) : 16; const bufferC = globalThis[otherType] ? new ArrayBuffer(16) : 16;
return [ return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
new CtorA(bufferA),
new CtorA(bufferA),
new CtorB(bufferB),
new CtorB(bufferC),
];
}); });
const expected = pairs.map(() => [true, false, false]); const expected = pairs.map(() => [true, false, false]);
const actual = pairs.map((pair) => [ const actual = pairs.map(pair => [isEqual(pair[0], pair[1]), isEqual(pair[0], pair[2]), isEqual(pair[2], pair[3])]);
isEqual(pair[0], pair[1]),
isEqual(pair[0], pair[2]),
isEqual(pair[2], pair[3]),
]);
expect(actual).toEqual(expected); expect(actual).toEqual(expected);
}); });
@ -539,33 +514,23 @@ describe('isEqual', () => {
}); });
it('should compare error objects', () => { it('should compare error objects', () => {
const pairs = [ const pairs = ['Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError'].map(
'Error', (type, index, errorTypes) => {
'EvalError', const otherType = errorTypes[++index % errorTypes.length];
'RangeError', // eslint-disable-next-line
'ReferenceError', // @ts-ignore
'SyntaxError', const CtorA = globalThis[type];
'TypeError', // eslint-disable-next-line
'URIError', // @ts-ignore
].map((type, index, errorTypes) => { const CtorB = globalThis[otherType];
const otherType = errorTypes[++index % errorTypes.length];
// eslint-disable-next-line
// @ts-ignore
const CtorA = globalThis[type];
// eslint-disable-next-line
// @ts-ignore
const CtorB = globalThis[otherType];
return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')]; return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
}); }
);
const expected = pairs.map(() => [true, false, false]); const expected = pairs.map(() => [true, false, false]);
const actual = pairs.map((pair) => [ const actual = pairs.map(pair => [isEqual(pair[0], pair[1]), isEqual(pair[0], pair[2]), isEqual(pair[2], pair[3])]);
isEqual(pair[0], pair[1]),
isEqual(pair[0], pair[2]),
isEqual(pair[2], pair[3]),
]);
expect(actual).toEqual(expected); expect(actual).toEqual(expected);
}); });
@ -583,9 +548,7 @@ describe('isEqual', () => {
}); });
it('should compare maps', () => { it('should compare maps', () => {
[ [[new Map(), new Map()]].forEach(maps => {
[new Map(), new Map()],
].forEach((maps) => {
const map1 = maps[0]; const map1 = maps[0];
const map2 = maps[1]; const map2 = maps[1];
@ -623,16 +586,13 @@ describe('isEqual', () => {
}); });
it('should compare promises by reference', () => { it('should compare promises by reference', () => {
[ [[Promise.resolve(1), Promise.resolve(1)]].forEach(promises => {
[Promise.resolve(1), Promise.resolve(1)], const promise1 = promises[0];
].forEach( const promise2 = promises[1];
(promises) => {
const promise1 = promises[0];
const promise2 = promises[1];
expect(isEqual(promise1, promise2)).toBe(false); expect(isEqual(promise1, promise2)).toBe(false);
expect(isEqual(promise1, promise1)).toBe(true); expect(isEqual(promise1, promise1)).toBe(true);
}); });
}); });
it('should compare regexes', () => { it('should compare regexes', () => {
@ -641,15 +601,11 @@ describe('isEqual', () => {
expect(isEqual(/x/gi, /x/g)).toBe(false); expect(isEqual(/x/gi, /x/g)).toBe(false);
expect(isEqual(/x/, /y/)).toBe(false); expect(isEqual(/x/, /y/)).toBe(false);
expect( expect(isEqual(/x/g, { global: true, ignoreCase: false, multiline: false, source: 'x' })).toBe(false);
isEqual(/x/g, { global: true, ignoreCase: false, multiline: false, source: 'x' })
).toBe(false);
}); });
it('should compare sets', () => { it('should compare sets', () => {
[ [[new Set(), new Set()]].forEach(sets => {
[new Set(), new Set()],
].forEach((sets) => {
const set1 = sets[0]; const set1 = sets[0];
const set2 = sets[1]; const set2 = sets[1];
@ -714,7 +670,6 @@ describe('isEqual', () => {
expect(isEqual(object1, object2)).toBe(false); expect(isEqual(object1, object2)).toBe(false);
}); });
it('should return `false` for objects with custom `toString` methods', () => { it('should return `false` for objects with custom `toString` methods', () => {
let primitive: any; let primitive: any;
const object = { const object = {
@ -725,7 +680,7 @@ describe('isEqual', () => {
const values = [true, null, 1, 'a', undefined]; const values = [true, null, 1, 'a', undefined];
const expected = values.map(stubFalse); const expected = values.map(stubFalse);
const actual = values.map((value) => { const actual = values.map(value => {
primitive = value; primitive = value;
return isEqual(object, value); return isEqual(object, value);
}); });

View File

@ -22,7 +22,7 @@ describe('isMatch', () => {
} }
interface FooConstructor { interface FooConstructor {
new(): Foo; new (): Foo;
} }
const Foo = function Foo(this: Foo) { const Foo = function Foo(this: Foo) {
@ -42,7 +42,7 @@ describe('isMatch', () => {
} }
interface FooConstructor { interface FooConstructor {
new(): Foo; new (): Foo;
} }
const Foo = function Foo(this: Foo) { const Foo = function Foo(this: Foo) {
@ -77,7 +77,7 @@ describe('isMatch', () => {
it(`should compare functions by reference`, () => { it(`should compare functions by reference`, () => {
const object1 = { a: noop }; const object1 = { a: noop };
const object2 = { a: () => { } }; const object2 = { a: () => {} };
const object3 = { a: {} }; const object3 = { a: {} };
expect(isMatch(object1, object1)).toBe(true); expect(isMatch(object1, object1)).toBe(true);
@ -86,16 +86,16 @@ describe('isMatch', () => {
}); });
it(`should work with a function for \`object\``, () => { it(`should work with a function for \`object\``, () => {
function Foo() { } function Foo() {}
Foo.a = { b: 2, c: 3 }; Foo.a = { b: 2, c: 3 };
expect(isMatch(Foo, { a: { b: 2 } })).toBe(true); expect(isMatch(Foo, { a: { b: 2 } })).toBe(true);
}); });
it(`should work with a function for \`source\``, () => { it(`should work with a function for \`source\``, () => {
function Foo() { } function Foo() {}
Foo.a = 1; Foo.a = 1;
Foo.b = function () { }; Foo.b = function () {};
Foo.c = 3; Foo.c = 3;
const objects = [{ a: 1 }, { a: 1, b: Foo.b, c: 3 }]; const objects = [{ a: 1 }, { a: 1, b: Foo.b, c: 3 }];
@ -112,7 +112,7 @@ describe('isMatch', () => {
} }
interface FooConstructor { interface FooConstructor {
new(arg: Partial<Foo>): Foo; new (arg: Partial<Foo>): Foo;
} }
const Foo = function Foo(this: Foo, object: Partial<Foo>) { const Foo = function Foo(this: Foo, object: Partial<Foo>) {

View File

@ -6,7 +6,7 @@ import { isSetMatch } from '../_internal/isSetMatch.ts';
/** /**
* Checks if the target matches the source by comparing their structures and values. * Checks if the target matches the source by comparing their structures and values.
* This function supports deep comparison for objects, arrays, maps, and sets. * This function supports deep comparison for objects, arrays, maps, and sets.
* *
* @param {unknown} target - The target value to match against. * @param {unknown} target - The target value to match against.
* @param {unknown} source - The source value to match with. * @param {unknown} source - The source value to match with.
* @returns {boolean} - Returns `true` if the target matches the source, otherwise `false`. * @returns {boolean} - Returns `true` if the target matches the source, otherwise `false`.

View File

@ -1,6 +1,6 @@
/** /**
* Checks if the given value is object-like. * Checks if the given value is object-like.
* *
* A value is object-like if its type is object and it is not null. * A value is object-like if its type is object and it is not null.
* *
* This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to an object-like value. * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to an object-like value.

View File

@ -3,7 +3,7 @@ import { isMatch } from './isMatch.ts';
/** /**
* Creates a function that performs a deep comparison between a given target and the source object. * Creates a function that performs a deep comparison between a given target and the source object.
* *
* @param {unknown} source - The source object to create the matcher from. * @param {unknown} source - The source object to create the matcher from.
* @returns {(target: unknown) => boolean} - Returns a function that takes a target object and returns `true` if the target matches the source, otherwise `false`. * @returns {(target: unknown) => boolean} - Returns a function that takes a target object and returns `true` if the target matches the source, otherwise `false`.
* *

View File

@ -1,11 +1,11 @@
/** /**
* Pads the start of a string with a given character until it reaches the specified length. * Pads the start of a string with a given character until it reaches the specified length.
* *
* If the length is less than or equal to the original string's length, or if the padding character is an empty string, * If the length is less than or equal to the original string's length, or if the padding character is an empty string,
* the original string is returned unchanged. * the original string is returned unchanged.
* *
* @param {string} str - The string to pad. * @param {string} str - The string to pad.
* @param {number} [length] - The length of the resulting string once padded. * @param {number} [length] - The length of the resulting string once padded.
* @param {string} [chars] - The character(s) to use for padding. * @param {string} [chars] - The character(s) to use for padding.
* @returns {string} - The padded string, or the original string if padding is not required. * @returns {string} - The padded string, or the original string if padding is not required.
* *
@ -17,4 +17,4 @@
*/ */
export function padStart(str: string, length = 0, chars = ' '): string { export function padStart(str: string, length = 0, chars = ' '): string {
return str.padStart(length, chars); return str.padStart(length, chars);
}; }

View File

@ -7,8 +7,8 @@
* @param {any} guard - Enables use as an iteratee for methods like `map`. * @param {any} guard - Enables use as an iteratee for methods like `map`.
* @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function. * @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function.
*/ */
export function ary<F extends (...args: any[]) => any>(func: F, n: number): ((...args: any[]) => ReturnType<F>) { export function ary<F extends (...args: any[]) => any>(func: F, n: number): (...args: any[]) => ReturnType<F> {
return function (this: any, ...args: Parameters<F>) { return function (this: any, ...args: Parameters<F>) {
return func.apply(this, args.slice(0, n)); return func.apply(this, args.slice(0, n));
}; };
}; }

View File

@ -56,7 +56,7 @@ export function debounce<F extends (...args: any[]) => void>(
timeoutId = setTimeout(() => { timeoutId = setTimeout(() => {
func(...args); func(...args);
timeoutId = null; timeoutId = null;
}, debounceMs) ; }, debounceMs);
} as F & { cancel: () => void }; } as F & { cancel: () => void };
const onAbort = function () { const onAbort = function () {

View File

@ -2,9 +2,9 @@ import { describe, it, expect } from 'vitest';
import { negate } from './negate'; import { negate } from './negate';
describe('negate', () => { describe('negate', () => {
it('should negate the given predicate function', () => { it('should negate the given predicate function', () => {
expect(typeof negate(() => true)).toBe('function'); expect(typeof negate(() => true)).toBe('function');
expect(negate(() => true)()).toBe(false); expect(negate(() => true)()).toBe(false);
expect(negate(() => false)()).toBe(true); expect(negate(() => false)()).toBe(true);
}); });
}); });

View File

@ -6,5 +6,5 @@
* @returns {F} The new negated function, which negates the boolean result of `func`. * @returns {F} The new negated function, which negates the boolean result of `func`.
*/ */
export function negate<F extends (...args: unknown[]) => boolean>(func: F): F { export function negate<F extends (...args: unknown[]) => boolean>(func: F): F {
return ((...args: any[]) => !func(...args)) as F; return ((...args: any[]) => !func(...args)) as F;
} }

View File

@ -7,6 +7,6 @@ import { ary } from './ary.ts';
* @param {F} func - The function to cap arguments for. * @param {F} func - The function to cap arguments for.
* @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function. * @returns {(...args: any[]) => ReturnType<F>} Returns the new capped function.
*/ */
export function unary<F extends (...args: any[]) => any>(func: F): ((...args: any[]) => ReturnType<F>) { export function unary<F extends (...args: any[]) => any>(func: F): (...args: any[]) => ReturnType<F> {
return ary(func, 1); return ary(func, 1);
}; }

View File

@ -55,8 +55,6 @@ describe('round function', () => {
it('handles edge cases where precision is not integer', () => { it('handles edge cases where precision is not integer', () => {
const value = 1.2345; const value = 1.2345;
const precision = 3.1; const precision = 3.1;
expect(() => round(value, precision)).toThrow( expect(() => round(value, precision)).toThrow('Precision must be an integer.');
'Precision must be an integer.'
);
}); });
}); });

View File

@ -61,7 +61,7 @@ export function clone<T>(obj: T): T {
if (typeof obj === 'object') { if (typeof obj === 'object') {
const prototype = Object.getPrototypeOf(obj); const prototype = Object.getPrototypeOf(obj);
const result = Object.create(prototype) const result = Object.create(prototype);
return Object.assign(result, obj); return Object.assign(result, obj);
} }
return obj; return obj;

View File

@ -32,7 +32,7 @@ describe('cloneDeep', () => {
expect(cloned).toEqual(arr); expect(cloned).toEqual(arr);
expect(cloned).not.toBe(arr); expect(cloned).not.toBe(arr);
}) });
it('should clone arrays with nested objects', () => { it('should clone arrays with nested objects', () => {
const arr = [{ a: 1 }, { b: 2 }, { c: 3 }]; const arr = [{ a: 1 }, { b: 2 }, { c: 3 }];
@ -337,7 +337,7 @@ describe('cloneDeep', () => {
expect(cloned).not.toBe(view); expect(cloned).not.toBe(view);
expect(cloned.getInt8(0)).toBe(view.getInt8(0)); expect(cloned.getInt8(0)).toBe(view.getInt8(0));
expect(cloned.getInt8(1)).toBe(view.getInt8(1)); expect(cloned.getInt8(1)).toBe(view.getInt8(1));
}) });
it('should clone buffers', () => { it('should clone buffers', () => {
const buffer = Buffer.from([1, 2, 3]); const buffer = Buffer.from([1, 2, 3]);
@ -346,5 +346,5 @@ describe('cloneDeep', () => {
expect(cloned).not.toBe(buffer); expect(cloned).not.toBe(buffer);
expect(cloned).toEqual(buffer); expect(cloned).toEqual(buffer);
}) });
}); });

View File

@ -1,17 +1,17 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from 'vitest';
import { flattenObject } from "./flattenObject"; import { flattenObject } from './flattenObject';
describe('flattenObject', function () { describe('flattenObject', function () {
it('flattens primitive values correctly', () => { it('flattens primitive values correctly', () => {
const result1 = flattenObject({ const result1 = flattenObject({
a: { a: {
b: 'yay' b: 'yay',
} },
}); });
expect(result1).toEqual({ expect(result1).toEqual({
'a.b': 'yay' 'a.b': 'yay',
}) });
const date = new Date(); const date = new Date();
@ -24,9 +24,9 @@ describe('flattenObject', function () {
null: null, null: null,
undefined: undefined, undefined: undefined,
date: date, date: date,
} },
} },
}) });
expect(result2).toEqual({ expect(result2).toEqual({
'a.b.string': 'hello world', 'a.b.string': 'hello world',
@ -35,8 +35,8 @@ describe('flattenObject', function () {
'a.b.null': null, 'a.b.null': null,
'a.b.undefined': undefined, 'a.b.undefined': undefined,
'a.b.date': date, 'a.b.date': date,
}) });
}) });
it('flattens multiple keys', () => { it('flattens multiple keys', () => {
const date = new Date(); const date = new Date();
@ -49,58 +49,58 @@ describe('flattenObject', function () {
d: { d: {
e: { e: {
f: { f: {
g: date g: date,
} },
} },
} },
}, },
h: { h: {
i: 'hi' i: 'hi',
} },
}); });
expect(result).toEqual({ expect(result).toEqual({
'a.b.c': 1, 'a.b.c': 1,
'a.d.e.f.g': date, 'a.d.e.f.g': date,
'h.i': 'hi' 'h.i': 'hi',
}) });
}) });
it('handles empty objects correctly', () => { it('handles empty objects correctly', () => {
const result = flattenObject({ const result = flattenObject({
a: { a: {
b: {} b: {},
} },
}); });
expect(result).toEqual({ expect(result).toEqual({
'a.b': {}, 'a.b': {},
}) });
}) });
it('handles `Buffer`s correctly', () => { it('handles `Buffer`s correctly', () => {
const result = flattenObject({ const result = flattenObject({
a: { a: {
b: Buffer.from('test') b: Buffer.from('test'),
} },
}); });
expect(result).toEqual({ expect(result).toEqual({
'a.b': Buffer.from('test') 'a.b': Buffer.from('test'),
}); });
}) });
it('handles `TypedArray`s correctly', () => { it('handles `TypedArray`s correctly', () => {
const result = flattenObject({ const result = flattenObject({
a: { a: {
b: new Uint8Array([1, 2, 3, 4]) b: new Uint8Array([1, 2, 3, 4]),
} },
}); });
expect(result).toEqual({ expect(result).toEqual({
'a.b': new Uint8Array([1, 2, 3, 4]) 'a.b': new Uint8Array([1, 2, 3, 4]),
}); });
}) });
it('handles numeric keys', () => { it('handles numeric keys', () => {
const result = flattenObject({ const result = flattenObject({
@ -108,31 +108,31 @@ describe('flattenObject', function () {
'02': { '02': {
'03': 1, '03': 1,
}, },
} },
}); });
expect(result).toEqual({ expect(result).toEqual({
'01.02.03': 1, '01.02.03': 1,
}); });
}) });
it('handles mixed keys', () => { it('handles mixed keys', () => {
const result = flattenObject({ const result = flattenObject({
'a1': { a1: {
'b2': { b2: {
'c3': 1, c3: 1,
}, },
} },
}); });
expect(result).toEqual({ expect(result).toEqual({
'a1.b2.c3': 1 'a1.b2.c3': 1,
}); });
}) });
it('handles arrays', () => { it('handles arrays', () => {
const result = flattenObject({ const result = flattenObject({
a: [1, 2, 3] a: [1, 2, 3],
}); });
expect(result).toEqual({ expect(result).toEqual({
@ -140,5 +140,5 @@ describe('flattenObject', function () {
'a.1': 2, 'a.1': 2,
'a.2': 3, 'a.2': 3,
}); });
}) });
}) });

View File

@ -1,11 +1,11 @@
import { isPlainObject } from "../predicate/isPlainObject.ts"; import { isPlainObject } from '../predicate/isPlainObject.ts';
/** /**
* Flattens a nested object into a single level object with dot-separated keys. * Flattens a nested object into a single level object with dot-separated keys.
* *
* @param {object} object - The object to flatten. * @param {object} object - The object to flatten.
* @returns {Record<string, any>} - The flattened object. * @returns {Record<string, any>} - The flattened object.
* *
* @example * @example
* const nestedObject = { * const nestedObject = {
* a: { * a: {
@ -15,9 +15,9 @@ import { isPlainObject } from "../predicate/isPlainObject.ts";
* }, * },
* d: [2, 3] * d: [2, 3]
* }; * };
* *
* const flattened = flattenObject(nestedObject); * const flattened = flattenObject(nestedObject);
* console.log(flattened); * console.log(flattened);
* // Output: * // Output:
* // { * // {
* // 'a.b.c': 1, * // 'a.b.c': 1,
@ -55,4 +55,4 @@ function flattenObjectImpl(object: object, prefix = ''): Record<string, any> {
} }
return result; return result;
} }

View File

@ -20,7 +20,7 @@ export function invert<K extends PropertyKey, V extends PropertyKey>(obj: Record
const result = {} as { [key in V]: K }; const result = {} as { [key in V]: K };
const keys = Object.keys(obj) as K[]; const keys = Object.keys(obj) as K[];
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
const key = keys[i]; const key = keys[i];
const value = obj[key]; const value = obj[key];

View File

@ -99,7 +99,7 @@ describe('isEqual', () => {
const buffer2 = new Uint8Array([1, 2, 3]).buffer; const buffer2 = new Uint8Array([1, 2, 3]).buffer;
expect(isEqual(buffer1, buffer2)).toBe(true); expect(isEqual(buffer1, buffer2)).toBe(true);
}) });
it('should return false for different array buffers', () => { it('should return false for different array buffers', () => {
const buffer1 = new Uint8Array([1, 2, 3]).buffer; const buffer1 = new Uint8Array([1, 2, 3]).buffer;
@ -111,5 +111,5 @@ describe('isEqual', () => {
const buffer4 = new Uint8Array([1, 2, 4]).buffer; const buffer4 = new Uint8Array([1, 2, 4]).buffer;
expect(isEqual(buffer3, buffer4)).toBe(false); expect(isEqual(buffer3, buffer4)).toBe(false);
}) });
}); });

View File

@ -1,12 +1,40 @@
import {
argumentsTag,
arrayBufferTag,
arrayTag,
bigInt64ArrayTag,
bigUint64ArrayTag,
booleanTag,
dataViewTag,
dateTag,
errorTag,
float32ArrayTag,
float64ArrayTag,
functionTag,
int16ArrayTag,
int32ArrayTag,
int8ArrayTag,
mapTag,
numberTag,
objectTag,
regexpTag,
setTag,
stringTag,
symbolTag,
uint16ArrayTag,
uint32ArrayTag,
uint8ArrayTag,
uint8ClampedArrayTag,
} from '../compat/_internal/tags.ts';
import { getSymbols } from '../compat/_internal/getSymbols.ts';
import { getTag } from '../compat/_internal/getTag.ts';
import { isPlainObject } from './isPlainObject.ts';
import { argumentsTag, arrayBufferTag, arrayTag, bigInt64ArrayTag, bigUint64ArrayTag, booleanTag, dataViewTag, dateTag, errorTag, float32ArrayTag, float64ArrayTag, functionTag, int16ArrayTag, int32ArrayTag, int8ArrayTag, mapTag, numberTag, objectTag, regexpTag, setTag, stringTag, symbolTag, uint16ArrayTag, uint32ArrayTag, uint8ArrayTag, uint8ClampedArrayTag } from "../compat/_internal/tags.ts"; declare var Buffer:
import { getSymbols } from "../compat/_internal/getSymbols.ts"; | {
import { getTag } from "../compat/_internal/getTag.ts"; isBuffer: (a: any) => boolean;
import { isPlainObject } from "./isPlainObject.ts"; }
| undefined;
declare var Buffer: {
isBuffer: (a: any) => boolean;
} | undefined;
/** /**
* Checks if two values are equal, including support for `Date`, `RegExp`, and deep object comparison. * Checks if two values are equal, including support for `Date`, `RegExp`, and deep object comparison.
@ -75,7 +103,7 @@ function areObjectsEqual(a: any, b: any, stack?: Map<any, any>) {
const x = a.valueOf(); const x = a.valueOf();
const y = b.valueOf(); const y = b.valueOf();
return x === y || Number.isNaN(x) && Number.isNaN(y); return x === y || (Number.isNaN(x) && Number.isNaN(y));
} }
case booleanTag: case booleanTag:
@ -132,7 +160,7 @@ function areObjectsEqual(a: any, b: any, stack?: Map<any, any>) {
const aValue = aValues[i]; const aValue = aValues[i];
const index = bValues.findIndex(bValue => { const index = bValues.findIndex(bValue => {
return areObjectsEqual(aValue, bValue, stack); return areObjectsEqual(aValue, bValue, stack);
}) });
if (index === -1) { if (index === -1) {
return false; return false;
@ -196,8 +224,7 @@ function areObjectsEqual(a: any, b: any, stack?: Map<any, any>) {
case objectTag: { case objectTag: {
const areEqualInstances = const areEqualInstances =
areObjectsEqual(a.constructor, b.constructor, stack) || areObjectsEqual(a.constructor, b.constructor, stack) || (isPlainObject(a) && isPlainObject(b));
(isPlainObject(a) && isPlainObject(b));
if (!areEqualInstances) { if (!areEqualInstances) {
return false; return false;
@ -236,4 +263,3 @@ function areObjectsEqual(a: any, b: any, stack?: Map<any, any>) {
stack.delete(b); stack.delete(b);
} }
} }

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { isPlainObject } from "./isPlainObject"; import { isPlainObject } from './isPlainObject';
describe('isPlainObject', () => { describe('isPlainObject', () => {
it('returns true for plain objects', () => { it('returns true for plain objects', () => {
@ -15,4 +15,4 @@ describe('isPlainObject', () => {
expect(isPlainObject(Buffer.from('123123'))).toBe(false); expect(isPlainObject(Buffer.from('123123'))).toBe(false);
expect(isPlainObject(new Uint8Array([1, 2, 3]))).toBe(false); expect(isPlainObject(new Uint8Array([1, 2, 3]))).toBe(false);
}); });
}); });

View File

@ -1,9 +1,9 @@
/** /**
* Checks if a given value is a plain object. * Checks if a given value is a plain object.
* *
* @param {object} object - The value to check. * @param {object} object - The value to check.
* @returns {boolean} - True if the value is a plain object, otherwise false. * @returns {boolean} - True if the value is a plain object, otherwise false.
* *
* @example * @example
* console.log(isPlainObject({})); // true * console.log(isPlainObject({})); // true
* console.log(isPlainObject([])); // false * console.log(isPlainObject([])); // false
@ -35,4 +35,4 @@ export function isPlainObject(object: object): boolean {
} }
return Object.getPrototypeOf(object) === proto; return Object.getPrototypeOf(object) === proto;
} }

View File

@ -1,13 +1,13 @@
import { timeout } from './timeout.ts'; import { timeout } from './timeout.ts';
/** /**
* Executes an async function and enforces a timeout. * Executes an async function and enforces a timeout.
* *
* If the promise does not resolve within the specified time, * If the promise does not resolve within the specified time,
* the timeout will trigger and the returned promise will be rejected. * the timeout will trigger and the returned promise will be rejected.
* *
* *
* @template T * @template T
* @param {() => Promise<T>} run - A function that returns a promise to be executed. * @param {() => Promise<T>} run - A function that returns a promise to be executed.
* @param {number} ms - The timeout duration in milliseconds. * @param {number} ms - The timeout duration in milliseconds.
* @returns {Promise<T>} A promise that resolves with the result of the `run` function or rejects if the timeout is reached. * @returns {Promise<T>} A promise that resolves with the result of the `run` function or rejects if the timeout is reached.

View File

@ -1,42 +1,40 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from 'vitest';
import { camelCase } from "./camelCase"; import { camelCase } from './camelCase';
describe("camelCase", () => { describe('camelCase', () => {
it("should change camel case to camel case", async () => { it('should change camel case to camel case', async () => {
expect(camelCase("camelCase")).toEqual("camelCase"); expect(camelCase('camelCase')).toEqual('camelCase');
}); });
it("should change space to camel case", async () => { it('should change space to camel case', async () => {
expect(camelCase("some whitespace")).toEqual("someWhitespace"); expect(camelCase('some whitespace')).toEqual('someWhitespace');
}); });
it("should change hyphen to camel case", async () => { it('should change hyphen to camel case', async () => {
expect(camelCase("hyphen-text")).toEqual("hyphenText"); expect(camelCase('hyphen-text')).toEqual('hyphenText');
}); });
it("should change Acronyms to small letter", async () => { it('should change Acronyms to small letter', async () => {
expect(camelCase("HTTPRequest")).toEqual("httpRequest"); expect(camelCase('HTTPRequest')).toEqual('httpRequest');
}); });
it("should handle leading and trailing whitespace", async () => { it('should handle leading and trailing whitespace', async () => {
expect(camelCase(" leading and trailing whitespace")).toEqual( expect(camelCase(' leading and trailing whitespace')).toEqual('leadingAndTrailingWhitespace');
"leadingAndTrailingWhitespace",
);
}); });
it("should handle special characters correctly", async () => { it('should handle special characters correctly', async () => {
expect(camelCase("special@characters!")).toEqual("specialCharacters"); expect(camelCase('special@characters!')).toEqual('specialCharacters');
}); });
it("should handle strings that are already in camel_case", async () => { it('should handle strings that are already in camel_case', async () => {
expect(camelCase("camel_case")).toEqual("camelCase"); expect(camelCase('camel_case')).toEqual('camelCase');
}); });
it("should work with an empty string", async () => { it('should work with an empty string', async () => {
expect(camelCase("")).toEqual(""); expect(camelCase('')).toEqual('');
}); });
it("should work with screaming camel case", async () => { it('should work with screaming camel case', async () => {
expect(camelCase("FOO_BAR")).toEqual("fooBar"); expect(camelCase('FOO_BAR')).toEqual('fooBar');
}); });
}); });

View File

@ -1,5 +1,5 @@
import { capitalize } from "./capitalize.ts"; import { capitalize } from './capitalize.ts';
import { getWords } from "./_internal/getWords.ts"; import { getWords } from './_internal/getWords.ts';
/** /**
* Converts a string to camel case. * Converts a string to camel case.
@ -20,11 +20,10 @@ export function camelCase(str: string): string {
const words = getWords(str); const words = getWords(str);
if (words.length === 0) { if (words.length === 0) {
return ""; return '';
} }
const [first, ...rest] = words; const [first, ...rest] = words;
return `${first.toLowerCase()}${rest.map((word) => capitalize(word)).join("") return `${first.toLowerCase()}${rest.map(word => capitalize(word)).join('')}`;
}`;
} }

View File

@ -13,5 +13,5 @@ export async function createPackageTarball() {
return { return {
path: tarballPath, path: tarballPath,
} };
} }

View File

@ -8,4 +8,4 @@ export async function createTmpDir() {
await fs.promises.mkdir(tmpdir, { recursive: true }); await fs.promises.mkdir(tmpdir, { recursive: true });
return tmpdir; return tmpdir;
} }

View File

@ -27,4 +27,4 @@ export async function* parseTar(tgz: Buffer) {
yield it; yield it;
it.resume(); it.resume();
} }
} }

Some files were not shown because too many files have changed in this diff Show More