Skip to content

Commit 73f4f71

Browse files
committed
feat: added get()
1 parent 4aa61db commit 73f4f71

3 files changed

Lines changed: 87 additions & 0 deletions

File tree

src/get.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { pathParts } from './pathParts.js';
2+
3+
import type { Path, PathValue } from './types/objects.js';
4+
5+
export function get<Input extends object, const InputPath extends Path<Input>>(
6+
input: Input,
7+
path: InputPath,
8+
): PathValue<Input, InputPath>;
9+
10+
export function get<const Input extends object, const InputPath extends string>(input: Input, path: InputPath): unknown;
11+
12+
export function get<const Input extends object, const InputPath extends Path<Input> | string>(
13+
input: Input,
14+
path: InputPath,
15+
): unknown {
16+
if (path === '') {
17+
return input;
18+
}
19+
20+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
21+
let current: any = input;
22+
23+
for (const part of pathParts(path)) {
24+
if (typeof current === 'object' && current !== null && part in current) {
25+
current = current[part];
26+
} else {
27+
return;
28+
}
29+
}
30+
31+
return current;
32+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export * from './delayAnimationFrame.js';
2323
export * from './delayAnimationFrames.js';
2424
export * from './describeInput.js';
2525
export * from './escapeRegExp.js';
26+
export * from './get.js';
2627
export * from './getDateString.js';
2728
export * from './getISODateString.js';
2829
export * from './getMaxValue.js';

test/get.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { describe, it, expect } from 'vitest';
2+
3+
import { get } from '../src/get.js';
4+
5+
describe('get()', () => {
6+
const input = {
7+
age: 100_000,
8+
name: {
9+
first: 'Test',
10+
last: 'Testerson',
11+
},
12+
sayHi(): void {
13+
console.log('Hi!');
14+
},
15+
role: [
16+
{
17+
job: {
18+
title: 'Developer',
19+
},
20+
},
21+
],
22+
};
23+
24+
it('returns a value from an object', () => {
25+
const lastName = get(input, 'name.last');
26+
const jobTitle = get(input, 'role.0.job.title');
27+
28+
expect(lastName).toBe(input.name.last);
29+
expect(jobTitle).toBe(input.role[0]?.job.title);
30+
});
31+
32+
it('Returns undefined when path is invalid', () => {
33+
const result = get(input, 'role.0.job.nonExistent');
34+
35+
expect(result).toBeUndefined();
36+
});
37+
38+
it('Handles built in objects', () => {
39+
const date = new Date();
40+
41+
const result = get(date, 'toString');
42+
43+
// eslint-disable-next-line @typescript-eslint/unbound-method
44+
expect(result).toBe(date.toString);
45+
});
46+
47+
it('Empty path returns input', () => {
48+
const date = new Date();
49+
50+
const result = get(date, '');
51+
52+
expect(result).toBe(date);
53+
});
54+
});

0 commit comments

Comments
 (0)