Skip to content

Commit ed2c74a

Browse files
dmaretskyigcanti
authored andcommitted
feat: Add Struct.entries (#5237)
Co-authored-by: Giulio Canti <giulio.canti@gmail.com>
1 parent 073a1b8 commit ed2c74a

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

.changeset/curvy-sloths-tickle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": minor
3+
---
4+
5+
Add `Struct.entries` function

packages/effect/dtslint/Struct.tst.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,4 +328,15 @@ describe("Struct", () => {
328328
.type.toBe<{ [x: `a${string}`]: number }>()
329329
})
330330
})
331+
332+
describe("entries", () => {
333+
it("excludes symbol keys", () => {
334+
const c = Symbol("c")
335+
const value = { a: "a", b: 1, [c]: 2 }
336+
// should not include symbol keys
337+
expect(Struct.entries(value)).type.toBe<Array<["a" | "b", string | number]>>()
338+
// when the object is passed as a parameter, the values should be narrowed
339+
expect(Struct.entries({ a: "a", b: 1, [c]: 2 })).type.toBe<Array<["a" | "b", "a" | 1]>>()
340+
})
341+
})
331342
})

packages/effect/src/Struct.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,25 @@ export const get =
219219
* @since 3.6.0
220220
*/
221221
export const keys = <T extends {}>(o: T): Array<(keyof T) & string> => Object.keys(o) as Array<(keyof T) & string>
222+
223+
/**
224+
* Retrieves the entries (key-value pairs) of an object, where keys are strings,
225+
* in a type-safe manner. Symbol keys are excluded from the result.
226+
*
227+
* @example
228+
* ```ts
229+
* import * as assert from "node:assert"
230+
* import { Struct } from "effect"
231+
*
232+
* const c = Symbol("c")
233+
* const value = { a: "foo", b: 1, [c]: true }
234+
*
235+
* const entries: Array<["a" | "b", string | number]> = Struct.entries(value)
236+
*
237+
* assert.deepStrictEqual(entries, [["a", "foo"], ["b", 1]])
238+
* ```
239+
*
240+
* @since 3.17.0
241+
*/
242+
export const entries = <const R>(obj: R): Array<[keyof R & string, R[keyof R & string]]> =>
243+
Object.entries(obj as any) as any

packages/effect/test/Struct.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,10 @@ describe("Struct", () => {
120120
strictEqual(pipe({ a: 1 }, Struct.get("a")), 1)
121121
strictEqual(pipe({}, Struct.get("a")), undefined)
122122
})
123+
124+
it("entries", () => {
125+
const c = Symbol("c")
126+
// should not include symbol keys
127+
deepStrictEqual(Struct.entries({ a: "a", b: 1, [c]: 2 }), [["a", "a"], ["b", 1]])
128+
})
123129
})

0 commit comments

Comments
 (0)