or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-map-obj

Map object keys and values into a new object

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/map-obj@5.0.x

To install, run

npx @tessl/cli install tessl/npm-map-obj@5.0.0

0

# Map Object

1

2

Map Object provides a utility function for mapping object keys and values into new objects, supporting both shallow and deep transformation of nested structures. It offers a flexible mapper function that allows developers to rename keys, transform values, and selectively exclude properties using a special skip symbol, with built-in support for recursive processing of nested objects and arrays while maintaining proper circular reference handling.

3

4

## Package Information

5

6

- **Package Name**: map-obj

7

- **Package Type**: npm

8

- **Language**: JavaScript/TypeScript

9

- **Installation**: `npm install map-obj`

10

11

## Core Imports

12

13

```javascript

14

import mapObject, { mapObjectSkip } from "map-obj";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const mapObject = require("map-obj");

21

const { mapObjectSkip } = require("map-obj");

22

```

23

24

## Basic Usage

25

26

```javascript

27

import mapObject, { mapObjectSkip } from "map-obj";

28

29

// Transform keys and values

30

const result = mapObject({ foo: "bar" }, (key, value) => [value, key]);

31

// Result: { bar: "foo" }

32

33

// Transform keys (e.g., normalize case)

34

const normalized = mapObject(

35

{ FOO: true, bAr: { bAz: true } },

36

(key, value) => [key.toLowerCase(), value]

37

);

38

// Result: { foo: true, bar: { bAz: true } }

39

40

// Deep transformation

41

const deepNormalized = mapObject(

42

{ FOO: true, bAr: { bAz: true } },

43

(key, value) => [key.toLowerCase(), value],

44

{ deep: true }

45

);

46

// Result: { foo: true, bar: { baz: true } }

47

48

// Exclude properties using skip symbol

49

const filtered = mapObject(

50

{ one: 1, two: 2 },

51

(key, value) => (value === 1 ? [key, value] : mapObjectSkip)

52

);

53

// Result: { one: 1 }

54

```

55

56

## Capabilities

57

58

### Map Object Function

59

60

Maps object keys and values into a new object using a provided mapper function.

61

62

```typescript { .api }

63

/**

64

* Map object keys and values into a new object

65

* @param source - The source object to copy properties from

66

* @param mapper - A mapping function that transforms keys and values

67

* @param options - Optional configuration for mapping behavior

68

* @returns New object with mapped keys and values

69

*/

70

function mapObject<

71

SourceObjectType extends Record<string, unknown>,

72

TargetObjectType extends Record<string, any>,

73

MappedObjectKeyType extends string,

74

MappedObjectValueType,

75

>(

76

source: SourceObjectType,

77

mapper: Mapper<SourceObjectType, MappedObjectKeyType, MappedObjectValueType>,

78

options: DeepOptions & TargetOptions<TargetObjectType>

79

): TargetObjectType & Record<string, unknown>;

80

81

function mapObject<

82

SourceObjectType extends Record<string, unknown>,

83

MappedObjectKeyType extends string,

84

MappedObjectValueType,

85

>(

86

source: SourceObjectType,

87

mapper: Mapper<SourceObjectType, MappedObjectKeyType, MappedObjectValueType>,

88

options: DeepOptions

89

): Record<string, unknown>;

90

91

function mapObject<

92

SourceObjectType extends Record<string, any>,

93

TargetObjectType extends Record<string, any>,

94

MappedObjectKeyType extends string,

95

MappedObjectValueType,

96

>(

97

source: SourceObjectType,

98

mapper: Mapper<SourceObjectType, MappedObjectKeyType, MappedObjectValueType>,

99

options: TargetOptions<TargetObjectType>

100

): TargetObjectType & {[K in MappedObjectKeyType]: MappedObjectValueType};

101

102

function mapObject<

103

SourceObjectType extends Record<string, any>,

104

MappedObjectKeyType extends string,

105

MappedObjectValueType,

106

>(

107

source: SourceObjectType,

108

mapper: Mapper<SourceObjectType, MappedObjectKeyType, MappedObjectValueType>,

109

options?: Options

110

): {[K in MappedObjectKeyType]: MappedObjectValueType};

111

```

112

113

**Usage Examples:**

114

115

```javascript

116

// Key transformation

117

const camelCased = mapObject(

118

{ "first-name": "John", "last-name": "Doe" },

119

(key, value) => [key.replace(/-(\w)/g, (_, char) => char.toUpperCase()), value]

120

);

121

// Result: { firstName: "John", lastName: "Doe" }

122

123

// Value transformation

124

const doubled = mapObject(

125

{ a: 1, b: 2, c: 3 },

126

(key, value) => [key, value * 2]

127

);

128

// Result: { a: 2, b: 4, c: 6 }

129

130

// Using target option

131

const target = { existing: "value" };

132

const merged = mapObject(

133

{ new: "data" },

134

(key, value) => [key, value],

135

{ target }

136

);

137

// Result: target object is modified and returned

138

```

139

140

### Map Object Skip Symbol

141

142

Special symbol returned from a mapper function to exclude a key from the result object.

143

144

```typescript { .api }

145

/**

146

* Return this value from a mapper function to remove a key from an object

147

*/

148

const mapObjectSkip: unique symbol;

149

```

150

151

**Usage Examples:**

152

153

```javascript

154

import mapObject, { mapObjectSkip } from "map-obj";

155

156

// Conditional inclusion

157

const adults = mapObject(

158

{ alice: 25, bob: 16, charlie: 30 },

159

(key, value) => (value >= 18 ? [key, value] : mapObjectSkip)

160

);

161

// Result: { alice: 25, charlie: 30 }

162

163

// Property filtering based on key patterns

164

const publicProps = mapObject(

165

{ name: "John", _private: "secret", age: 30, _id: 123 },

166

(key, value) => (key.startsWith("_") ? mapObjectSkip : [key, value])

167

);

168

// Result: { name: "John", age: 30 }

169

```

170

171

## Types

172

173

### Mapper Function Type

174

175

```typescript { .api }

176

type Mapper<

177

SourceObjectType extends Record<string, any>,

178

MappedObjectKeyType extends string,

179

MappedObjectValueType,

180

> = (

181

sourceKey: keyof SourceObjectType,

182

sourceValue: SourceObjectType[keyof SourceObjectType],

183

source: SourceObjectType

184

) => [

185

targetKey: MappedObjectKeyType,

186

targetValue: MappedObjectValueType,

187

mapperOptions?: MapperOptions,

188

] | typeof mapObjectSkip;

189

```

190

191

### Options Interface

192

193

```typescript { .api }

194

interface Options {

195

/**

196

* Recurse nested objects and objects in arrays

197

* @default false

198

*/

199

readonly deep?: boolean;

200

201

/**

202

* The target object to map properties on to

203

* @default {}

204

*/

205

readonly target?: Record<string, any>;

206

}

207

```

208

209

### Deep Options Interface

210

211

```typescript { .api }

212

interface DeepOptions extends Options {

213

readonly deep: true;

214

}

215

```

216

217

### Target Options Interface

218

219

```typescript { .api }

220

interface TargetOptions<TargetObjectType extends Record<string, any>> extends Options {

221

readonly target: TargetObjectType;

222

}

223

```

224

225

### Mapper Options Interface

226

227

```typescript { .api }

228

interface MapperOptions {

229

/**

230

* Whether targetValue should be recursed

231

* Requires deep: true

232

* @default true

233

*/

234

readonly shouldRecurse?: boolean;

235

}

236

```

237

238

## Advanced Usage

239

240

### Deep Object Mapping

241

242

```javascript

243

const nested = {

244

user: {

245

profile: {

246

firstName: "John",

247

lastName: "Doe"

248

},

249

preferences: ["email", "sms"]

250

}

251

};

252

253

const normalized = mapObject(

254

nested,

255

(key, value) => [key.toLowerCase(), value],

256

{ deep: true }

257

);

258

// All nested keys are transformed recursively

259

```

260

261

### Selective Recursion Control

262

263

```javascript

264

const data = {

265

metadata: { version: "1.0", author: "John" },

266

content: { title: "Example", body: "Content here" }

267

};

268

269

const result = mapObject(

270

data,

271

(key, value) => {

272

if (key === "metadata") {

273

// Don't recurse into metadata

274

return [key, value, { shouldRecurse: false }];

275

}

276

return [key.toUpperCase(), value];

277

},

278

{ deep: true }

279

);

280

// metadata object is not recursively transformed

281

```

282

283

### Circular Reference Handling

284

285

```javascript

286

const obj = { name: "test" };

287

obj.self = obj; // Create circular reference

288

289

const mapped = mapObject(

290

obj,

291

(key, value) => [key.toUpperCase(), value],

292

{ deep: true }

293

);

294

// Circular references are handled automatically using WeakMap tracking

295

```

296

297

## Error Handling

298

299

The `mapObject` function validates its input and throws `TypeError` in the following cases:

300

301

- When the first argument is not an object: `TypeError: Expected an object, got \`value\` (type)`

302

- When the first argument is an array: `TypeError: Expected an object, got an array`

303

304

```javascript

305

try {

306

mapObject(null, (k, v) => [k, v]);

307

} catch (error) {

308

console.log(error.message); // "Expected an object, got `null` (object)"

309

}

310

311

try {

312

mapObject([1, 2, 3], (k, v) => [k, v]);

313

} catch (error) {

314

console.log(error.message); // "Expected an object, got an array"

315

}

316

```