-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2d234d8
commit 827c185
Showing
7 changed files
with
99 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { expect, test } from 'vitest' | ||
import { hasField } from './hasField.js' | ||
|
||
test('hasField infers that a field exists on an unknown object', () => { | ||
const obj: unknown = { id: 1 } | ||
expect(hasField(obj, 'id') ? obj.id : 0).toBe(1) | ||
}) | ||
|
||
test.each([ | ||
{ obj: { a: 1 }, key: 'a', expected: true }, | ||
{ obj: { a: 1 }, key: 'b', expected: false }, | ||
{ obj: {}, key: 'a', expected: false }, | ||
{ obj: undefined, key: 'a', expected: false }, | ||
])('hasField checks that a field exists on an unknown object', ({ obj, key, expected }) => { | ||
expect(hasField(obj, key)).toBe(expected) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* Checks if the given object has the specified field. | ||
*/ | ||
export const hasField = <P extends PropertyKey>(obj: unknown, key: P): obj is Record<P, unknown> => | ||
obj != null && typeof obj === 'object' && key in obj | ||
|
||
/* | ||
* Example: | ||
* const obj: { data: unknown } | { error: string } | unknown = ... | ||
* hasField(obj, 'data') | ||
* ? JSON.stringify(obj.data) // inferred that the data field exists | ||
* : obj?.error // inferred that it's nullable or has error field | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './hasField.js' | ||
export * from './pickFields.js' | ||
export * from './omitFields.js' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { expect, test } from 'vitest' | ||
import { omitFields } from './omitFields.js' | ||
|
||
test('omitFields omits a field from an object', () => { | ||
expect(omitFields({ a: 1, b: 2, c: 3 }, 'b')).toMatchObject({ a: 1, c: 3 }) | ||
}) | ||
|
||
test('omitFields omits multiple fields from an object', () => { | ||
expect(omitFields({ a: 1, b: 2, c: 3 }, 'b', 'c')).toMatchObject({ a: 1 }) | ||
}) | ||
|
||
test('omitFields returns same obj if no keys are specified', () => { | ||
const obj = { a: 1, b: 2, c: 3 } | ||
expect(omitFields(obj)).toBe(obj) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* Omits specified fields from an object and returns a copy without those fields. | ||
*/ | ||
export const omitFields = <T extends Record<PropertyKey, unknown>, P extends keyof T>(obj: T, ...keys: P[]): Omit<T, P> => { | ||
if (keys.length === 0) return obj | ||
|
||
const copy = { ...obj } | ||
for (const k of keys) { | ||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete | ||
delete copy[k] | ||
} | ||
return copy | ||
} | ||
|
||
/* | ||
* Example: | ||
* const order = { id: ..., date: ..., customer: ..., status: ..., items: [...] } | ||
* const result = omitFields(order, 'customer', 'status') // { id: ..., date: ..., items: [...] } | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { expect, test } from 'vitest' | ||
import { pickFields } from './pickFields.js' | ||
|
||
test('pickFields picks a field from an object', () => { | ||
expect(pickFields({ a: 1, b: 2, c: 3 }, 'b')).toMatchObject({ b: 2 }) | ||
}) | ||
|
||
test('pickFields picks multiple fields from an object', () => { | ||
expect(pickFields({ a: 1, b: 2, c: 3 }, 'a', 'b')).toMatchObject({ a: 1, b: 2 }) | ||
}) | ||
|
||
test('pickFields returns same obj if no keys are specified', () => { | ||
const obj = { a: 1, b: 2, c: 3 } | ||
expect(pickFields(obj)).toBe(obj) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* Picks specific fields from an object and returns a copy with only those fields. | ||
*/ | ||
export const pickFields = <T extends Record<PropertyKey, unknown>, P extends keyof T>(obj: T, ...keys: P[]): Pick<T, P> => { | ||
if (keys.length === 0) return obj | ||
|
||
const copy = {} as Pick<T, P> | ||
for (const k of keys) { | ||
copy[k] = obj[k] | ||
} | ||
return copy | ||
} | ||
|
||
/* | ||
* Example: | ||
* const order = { id: ..., date: ..., customer: ..., status: ..., items: [...] } | ||
* const result = pickFields(order, 'id', 'date') // { id: ..., date: ... } | ||
*/ |