diff --git a/readme.md b/readme.md index 14cbcab..67a4ad2 100644 --- a/readme.md +++ b/readme.md @@ -36,6 +36,7 @@ import {isDefined} from 'ts-extras'; - [`arrayIncludes`](source/array-includes.ts) - An alternative to `Array#includes()` that properly acts as a type guard. - [`objectKeys`](source/object-keys.ts) - A strongly-typed version of `Object.keys()`. - [`objectEntries`](source/object-entries.ts) - A strongly-typed version of `Object.entries()`. +- [`objectFromEntries`](source/object-from-entries.ts) - A strongly-typed version of `Object.fromEntries()`. - [`objectHasOwn`](source/object-has-own.ts) - A strongly-typed version of `Object.hasOwn()`. - [`isFinite`](source/is-finite.ts) - A strongly-typed version of `Number.isFinite()`. - [`isInteger`](source/is-integer.ts) - A strongly-typed version of `Number.isInteger()`. diff --git a/source/index.ts b/source/index.ts index 73bdb08..db5620b 100644 --- a/source/index.ts +++ b/source/index.ts @@ -4,5 +4,6 @@ export {isEmpty} from './is-empty.js'; export {asMutable} from './as-mutable.js'; export {arrayIncludes} from './array-includes.js'; export {objectKeys} from './object-keys.js'; +export {objectFromEntries} from './object-from-entries.js'; export {objectEntries} from './object-entries.js'; export {objectHasOwn} from './object-has-own.js'; diff --git a/source/object-from-entries.ts b/source/object-from-entries.ts new file mode 100644 index 0000000..90fec81 --- /dev/null +++ b/source/object-from-entries.ts @@ -0,0 +1,32 @@ +/** +A strongly-typed version of `Object.fromEntries()`. + +This is useful since `Object.fromEntries()` always returns `{[key: string]: T}`. This function returns a strongly-typed object from the given array of entries. + +- [TypeScript issues about this](https://github.com/microsoft/TypeScript/issues/35745) + +@example +``` +import {objectFromEntries} from 'ts-extras'; + +const stronglyTypedObjectFromEntries = objectFromEntries([ + ['a', 123], + ['b', 'someString'], + ['c', true], +]); +//=> {a: number; b: string; c: boolean} + +const untypedEntries = Object.fromEntries(entries); +//=> {[key: string]: string} +``` + +@category Improved builtin +@category Type guard +*/ +export function objectFromEntries>(value: Entries): { + [K in Extract[0]]: Extract[1] +} { + return Object.fromEntries(value) as { + [K in Extract[0]]: Extract[1] + }; +} diff --git a/test/object-from-entries.ts b/test/object-from-entries.ts new file mode 100644 index 0000000..a97f0b8 --- /dev/null +++ b/test/object-from-entries.ts @@ -0,0 +1,26 @@ +import test from 'ava'; +import {expectTypeOf} from 'expect-type'; +import {objectFromEntries} from '../source/index.js'; + +test('objectFromEntries()', t => { + type ObjectFromEntries = { + [x: symbol]: boolean; + 1: number; + stringKey: string; + }; + + const symbolKey = Symbol('symbolKey'); + + const objectFromEntries_ = objectFromEntries([ + [1, 123], + ['stringKey', 'someString'], + [symbolKey, true], + ]); + + expectTypeOf(objectFromEntries_); + t.deepEqual(objectFromEntries_, { + 1: 123, + stringKey: 'someString', + [symbolKey]: true, + }); +});