ts-serializable 4.2.2 → 4.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,28 +1,232 @@
1
- Serializable
2
- =====
1
+ # ts-serializable
2
+
3
+ > Powerful and flexible TypeScript/JavaScript library for serialization and deserialization with decorators
4
+
5
+ [![npm version](https://img.shields.io/npm/v/ts-serializable.svg)](https://www.npmjs.com/package/ts-serializable)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## ✨ Features
9
+
10
+ - 🎯 **Type-safe** - Convert JSON to strongly-typed class instances
11
+ - 🎨 **Decorator-based** - Clean and intuitive API using TypeScript decorators
12
+ - 🔄 **Bidirectional** - Serialize to JSON and deserialize from JSON
13
+ - 🐍 **Naming Strategies** - Support for snake_case, camelCase, PascalCase, kebab-case
14
+ - 📦 **Nested Objects** - Handle complex object hierarchies and arrays
15
+ - 🔒 **Flexible** - Works with or without class inheritance
16
+ - 📝 **FormData Support** - Built-in conversion to FormData for file uploads
17
+ - ⚡ **Lightweight** - Minimal dependencies and small bundle size
18
+
19
+ ## 📋 Table of Contents
20
+
21
+ - [Installation](#-installation)
22
+ - [Quick Start](#-quick-start)
23
+ - [Core Concepts](#-core-concepts)
24
+ - [Decorators](#-decorators)
25
+ - [Advanced Usage](#-advanced-usage)
26
+ - [Standalone Functions](#-standalone-functions)
27
+ - [Naming Strategies](#-naming-strategies)
28
+ - [Configuration Settings](#️-configuration-settings)
29
+ - [View Models and DTOs](#-view-models-and-dtos)
30
+ - [FormData Conversion](#-formdata-conversion)
31
+ - [Additional Features](#-additional-features)
32
+ - [API Reference](#-api-reference)
33
+ - [Contributing](#-contributing)
34
+ - [License](#-license)
35
+
36
+ ## 🚀 Installation
37
+
38
+ ```bash
39
+ npm install ts-serializable reflect-metadata
40
+ ```
41
+
42
+ **Important:** This library requires the Metadata Reflection API. Import `reflect-metadata` at the entry point of your application:
43
+
44
+ ```typescript
45
+ // At the top of your main file (e.g., index.ts or main.ts)
46
+ import "reflect-metadata";
47
+ ```
48
+
49
+ ## 🎯 Quick Start
50
+
51
+ Here's a simple example to get you started:
52
+
53
+ ```typescript
54
+ import { jsonProperty, Serializable } from "ts-serializable";
55
+
56
+ class User extends Serializable {
57
+ @jsonProperty(String)
58
+ public firstName: string = '';
59
+
60
+ @jsonProperty(String)
61
+ public lastName: string = '';
62
+
63
+ @jsonProperty(Number)
64
+ public age: number = 0;
65
+
66
+ public getFullName(): string {
67
+ return `${this.firstName} ${this.lastName}`;
68
+ }
69
+ }
70
+
71
+ // Deserialize from JSON
72
+ const json = { firstName: "John", lastName: "Doe", age: 30 };
73
+ const user = User.fromJSON(json);
74
+
75
+ console.log(user.getFullName()); // "John Doe"
76
+ console.log(user instanceof User); // true
77
+
78
+ // Serialize back to JSON
79
+ const jsonOutput = user.toJSON();
80
+ console.log(JSON.stringify(jsonOutput)); // {"firstName":"John","lastName":"Doe","age":30}
81
+ ```
82
+
83
+ ### Why Use ts-serializable?
84
+
85
+ **Without ts-serializable:**
86
+
87
+ ```typescript
88
+ const user: object = JSON.parse(jsonString);
89
+ user.getFullName(); // ❌ Runtime Error: user.getFullName is not a function
90
+ ```
91
+
92
+ **With ts-serializable:**
93
+
94
+ ```typescript
95
+ const user: User = User.fromJSON(jsonString);
96
+ user.getFullName(); // ✅ Works perfectly and returns a string
97
+ ```
98
+
99
+ ## 🎓 Core Concepts
100
+
101
+ ### Type Safety
3
102
 
4
- Small library for deserialization and serialization for JavaScript and TypeScript
103
+ The `@jsonProperty` decorator tells the library what types are acceptable for each property. If a JSON value doesn't match the expected type, the property will retain its default value.
5
104
 
6
- Description
7
- ------
105
+ ```typescript
106
+ class Product extends Serializable {
107
+ @jsonProperty(String)
108
+ public name: string = '';
109
+
110
+ @jsonProperty(Number)
111
+ public price: number = 0;
112
+
113
+ @jsonProperty(Date)
114
+ public releaseDate: Date = new Date();
115
+ }
116
+ ```
117
+
118
+ ### Default Values
119
+
120
+ Always provide default values for properties decorated with `@jsonProperty`. This ensures type safety and provides fallback values when deserialization encounters issues.
121
+
122
+ ### Error Handling
123
+
124
+ By default, the library logs errors to the console but doesn't throw exceptions. For stricter behavior, override the `onWrongType` method:
125
+
126
+ ```typescript
127
+ class StrictUser extends Serializable {
128
+ @jsonProperty(String)
129
+ public name: string = '';
130
+
131
+ protected onWrongType(prop: string, message: string, value: unknown): void {
132
+ throw new Error(`Invalid property "${prop}": ${message}`);
133
+ }
134
+ }
135
+ ```
8
136
 
9
- - For working, this library needs the Metadata Reflection API. If your platform (browser/Node.js) doesn't support it, you must use a polyfill. Example: [reflect-metadata](https://www.npmjs.com/package/reflect-metadata)
137
+ ## 🎨 Decorators
10
138
 
11
- - By default, the library doesn't crash on wrong types in JSON and returns the default value on the wrong property. If you need more secure behavior, you must override the method `onWrongType` on the `Serializable` object and throw an exception in this method, according to your logic.
139
+ ### @jsonProperty
12
140
 
13
- Installation
14
- ------
141
+ Specifies the accepted types for a property during deserialization.
15
142
 
16
- You can use the following command to install this package:
143
+ ```typescript
144
+ @jsonProperty(...types: AcceptedTypes[])
145
+ ```
146
+
147
+ **Examples:**
148
+
149
+ ```typescript
150
+ // Single type
151
+ @jsonProperty(String)
152
+ public name: string = '';
17
153
 
18
- ``` bash
19
- npm install ts-serializable
154
+ // Multiple types (union)
155
+ @jsonProperty(Number, null)
156
+ public age: number | null = null;
157
+
158
+ // Arrays
159
+ @jsonProperty([String])
160
+ public tags: string[] = [];
161
+
162
+ // Nested objects
163
+ @jsonProperty(Address)
164
+ public address: Address = new Address();
165
+
166
+ // Optional properties
167
+ @jsonProperty(String, void 0)
168
+ public middleName?: string = void 0;
20
169
  ```
21
170
 
22
- Usage
23
- ------
171
+ ### @jsonIgnore
172
+
173
+ Excludes a property from serialization.
24
174
 
25
- This example is written in TypeScript, but if you remove typing, it will also work in JavaScript.
175
+ ```typescript
176
+ @jsonIgnore()
177
+ ```
178
+
179
+ **Example:**
180
+
181
+ ```typescript
182
+ class User extends Serializable {
183
+ @jsonProperty(String)
184
+ public username: string = '';
185
+
186
+ @jsonIgnore()
187
+ public password: string = ''; // Won't be included in toJSON()
188
+ }
189
+ ```
190
+
191
+ ### @jsonName
192
+
193
+ Specifies a custom JSON property name.
194
+
195
+ ```typescript
196
+ @jsonName(name: string)
197
+ ```
198
+
199
+ **Example:**
200
+
201
+ ```typescript
202
+ class User extends Serializable {
203
+ @jsonName("user_id")
204
+ @jsonProperty(Number)
205
+ public userId: number = 0; // Maps to "user_id" in JSON
206
+ }
207
+ ```
208
+
209
+ ### @jsonObject
210
+
211
+ Configures serialization settings at the class level.
212
+
213
+ ```typescript
214
+ @jsonObject(settings?: Partial<SerializationSettings>)
215
+ ```
216
+
217
+ **Example:**
218
+
219
+ ```typescript
220
+ @jsonObject({ namingStrategy: new SnakeCaseNamingStrategy() })
221
+ class User extends Serializable {
222
+ @jsonProperty(String)
223
+ public firstName: string = ''; // Automatically maps to "first_name"
224
+ }
225
+ ```
226
+
227
+ ## 🔧 Advanced Usage
228
+
229
+ This example is written in TypeScript, but it also works in JavaScript (without type annotations).
26
230
 
27
231
  ```typescript
28
232
  import { jsonProperty, Serializable } from "ts-serializable";
@@ -88,10 +292,145 @@ user.getFullName(); // works fine and returns a string
88
292
  user.getAge(); // works fine and returns a number
89
293
  ```
90
294
 
91
- Naming strategies
92
- ------
295
+ ## 🔧 Standalone Functions
296
+
297
+ The library provides standalone utility functions `fromJSON` and `toJSON` that can be used with any objects, not just classes that extend `Serializable`. This is useful when you want to use the serialization features without inheritance.
298
+
299
+ fromJSON Function:
300
+
301
+ The `fromJSON` function populates an existing object instance with data from JSON, using decorator metadata for type conversion.
302
+
303
+ ```typescript
304
+ import { fromJSON, jsonProperty } from "ts-serializable";
305
+
306
+ class Product {
307
+ @jsonProperty(String)
308
+ public name: string = '';
309
+
310
+ @jsonProperty(Number)
311
+ public price: number = 0;
312
+
313
+ @jsonProperty(Date)
314
+ public releaseDate: Date = new Date();
315
+ }
316
+
317
+ const json = {
318
+ name: "Laptop",
319
+ price: 999.99,
320
+ releaseDate: "2024-01-15T10:00:00.000Z"
321
+ };
322
+
323
+ const product = new Product();
324
+ fromJSON(product, json);
325
+
326
+ console.log(product.name); // "Laptop"
327
+ console.log(product.price); // 999.99
328
+ console.log(product.releaseDate instanceof Date); // true
329
+ ```
330
+
331
+ Benefits:
332
+
333
+ - Works with plain classes (no need to extend `Serializable`)
334
+ - Respects all decorators (`@jsonProperty`, `@jsonName`, `@jsonIgnore`)
335
+ - Supports naming strategies
336
+ - Handles nested objects and arrays
337
+ - Type-safe deserialization
338
+
339
+ toJSON Function:
340
+
341
+ The `toJSON` function serializes an object to a plain JavaScript object, respecting decorators and naming strategies.
342
+
343
+ ```typescript
344
+ import { toJSON, jsonProperty, jsonIgnore, jsonName } from "ts-serializable";
345
+
346
+ class User {
347
+ @jsonProperty(String)
348
+ public firstName: string = 'John';
349
+
350
+ @jsonProperty(String)
351
+ @jsonName("family_name")
352
+ public lastName: string = 'Doe';
353
+
354
+ @jsonIgnore()
355
+ public password: string = 'secret123';
356
+
357
+ @jsonProperty(Number)
358
+ public age: number = 30;
359
+ }
360
+
361
+ const user = new User();
362
+ const json = toJSON(user);
363
+
364
+ console.log(json);
365
+ // Output: {
366
+ // firstName: "John",
367
+ // family_name: "Doe",
368
+ // age: 30
369
+ // }
370
+ // Note: password is excluded due to @jsonIgnore
371
+ ```
372
+
373
+ Benefits:
374
+
375
+ - Works with both `Serializable` instances and plain objects
376
+ - Respects `@jsonIgnore` decorator
377
+ - Applies `@jsonName` transformations
378
+ - Supports naming strategies
379
+ - Returns plain object ready for `JSON.stringify()`
380
+
381
+ Using Functions Together:
382
+
383
+ You can use both functions together for complete serialization/deserialization workflows:
384
+
385
+ ```typescript
386
+ import { fromJSON, toJSON, jsonProperty, jsonObject } from "ts-serializable";
387
+ import { SnakeCaseNamingStrategy } from "ts-serializable";
388
+
389
+ @jsonObject({ namingStrategy: new SnakeCaseNamingStrategy() })
390
+ class ApiRequest {
391
+ @jsonProperty(String)
392
+ public requestId: string = '';
393
+
394
+ @jsonProperty(String)
395
+ public userName: string = '';
396
+
397
+ @jsonProperty([String])
398
+ public userTags: string[] = [];
399
+ }
400
+
401
+ // Deserialize from API response
402
+ const apiData = {
403
+ request_id: "REQ-12345",
404
+ user_name: "john_doe",
405
+ user_tags: ["premium", "verified"]
406
+ };
407
+
408
+ const request = new ApiRequest();
409
+ fromJSON(request, apiData);
410
+
411
+ console.log(request.requestId); // "REQ-12345"
412
+ console.log(request.userName); // "john_doe"
413
+
414
+ // Serialize for sending to API
415
+ const jsonToSend = toJSON(request);
416
+ console.log(jsonToSend);
417
+ // Output: {
418
+ // request_id: "REQ-12345",
419
+ // user_name: "john_doe",
420
+ // user_tags: ["premium", "verified"]
421
+ // }
422
+ ```
423
+
424
+ ## 🐍 Naming Strategies
425
+
426
+ The library supports automatic conversion between different naming conventions, making it easy to work with APIs that use different naming styles. Supported strategies include:
93
427
 
94
- Supported conversion between different naming cases, such as SnakeCase, KebabCase, PascalCase and CamelCase. Also, you can set a custom name for a property of a JSON object.
428
+ - **SnakeCaseNamingStrategy** - `user_name`
429
+ - **CamelCaseNamingStrategy** - `userName`
430
+ - **PascalCaseNamingStrategy** - `UserName`
431
+ - **KebabCaseNamingStrategy** - `user-name`
432
+
433
+ You can also use the `@jsonName` decorator for custom property names.
95
434
 
96
435
  ```typescript
97
436
  const json = {
@@ -127,10 +466,9 @@ user.dateOfBirth?.toISOString() === json.date_of_birth; // true
127
466
  user.veryStrangePropertyName === json["very::strange::json:name"]; // true
128
467
  ```
129
468
 
130
- Settings
131
- ------
469
+ ## ⚙️ Configuration Settings
132
470
 
133
- How to specify settings:
471
+ You can customize serialization behavior at three levels:
134
472
 
135
473
  ```typescript
136
474
  // Global settings
@@ -154,10 +492,9 @@ Supported settings:
154
492
  - **defaultValueHandling**, enum, default Ignore - ...coming soon.
155
493
  - **logLevel**, enum, default Warning - ...coming soon.
156
494
 
157
- View-Models from Backend Models
158
- ------
495
+ ## 🎭 View Models and DTOs
159
496
 
160
- If you need to create a view-model from a DTO or entities model, you can use the same model. Just add a VM property to the DTO or entities model and mark this property with the @jsonIgnore() decorator, and this property will not be serialized to JSON.
497
+ If you need to create view-models from DTO or entity models, you can add view-specific properties and mark them with `@jsonIgnore()` to exclude them from serialization.
161
498
 
162
499
  ```typescript
163
500
  import { jsonProperty, jsonIgnore, Serializable } from "ts-serializable";
@@ -181,38 +518,337 @@ JSON.stringify(user);
181
518
  // Result: {"firstName":"","familyName":""}
182
519
  ```
183
520
 
184
- Class to FormData
185
- ------
521
+ ## 📤 FormData Conversion
186
522
 
187
- Sometimes classes contain properties with the File type. Sending such classes via JSON is a heavy task. Converting a file property to JSON can freeze the interface for a few seconds if the file is large. A much better solution is to send an Ajax form. Example:
523
+ When working with file uploads, converting files to JSON (base64) can freeze the UI for large files. The library provides built-in FormData conversion as a more efficient alternative.
188
524
 
189
- ```typescript
190
- import { Serializable } from "ts-serializable";
525
+ ### Basic Usage
191
526
 
192
- export class User extends Serializable {
527
+ ```typescript
528
+ import { Serializable, jsonProperty } from "ts-serializable";
193
529
 
194
- public firstName: string = '';
530
+ class UserProfile extends Serializable {
531
+ @jsonProperty(String)
532
+ public name: string = '';
195
533
 
196
- public familyName: File | null = null;
534
+ @jsonProperty(Number)
535
+ public age: number = 0;
197
536
 
537
+ @jsonProperty(File, null)
538
+ public avatar: File | null = null;
198
539
  }
199
540
 
200
- // ... send file function ...
541
+ const profile = new UserProfile();
542
+ profile.name = "John Doe";
543
+ profile.age = 30;
544
+ profile.avatar = fileInput.files[0]; // File from <input type="file">
545
+
546
+ // Convert to FormData
547
+ const formData = profile.toFormData();
201
548
 
202
- await fetch("api/sendFile", {
549
+ // Send via fetch
550
+ await fetch("/api/profile", {
203
551
  method: "POST",
204
- body: user.toFormData() // <- serialization class to FormData
552
+ body: formData
205
553
  });
554
+ ```
555
+
556
+ **Resulting FormData entries:**
557
+
558
+ ```text
559
+ name: "John Doe"
560
+ age: "30"
561
+ avatar: [File object]
562
+ ```
563
+
564
+ ### Complex Object Graphs
565
+
566
+ The library handles nested objects and arrays intelligently, using dot notation for nested properties and indices for arrays:
567
+
568
+ ```typescript
569
+ import { Serializable, jsonProperty, jsonIgnore } from "ts-serializable";
570
+
571
+ class Address extends Serializable {
572
+ @jsonProperty(String)
573
+ public street: string = '';
574
+
575
+ @jsonProperty(String)
576
+ public city: string = '';
577
+
578
+ @jsonProperty(String)
579
+ public country: string = '';
580
+ }
206
581
 
582
+ class Document extends Serializable {
583
+ @jsonProperty(String)
584
+ public title: string = '';
585
+
586
+ @jsonProperty(File, null)
587
+ public file: File | null = null;
588
+ }
589
+
590
+ class Employee extends Serializable {
591
+ @jsonProperty(String)
592
+ public firstName: string = '';
593
+
594
+ @jsonProperty(String)
595
+ public lastName: string = '';
596
+
597
+ @jsonProperty(Number)
598
+ public salary: number = 0;
599
+
600
+ @jsonProperty(Address)
601
+ public homeAddress: Address = new Address();
602
+
603
+ @jsonProperty([Document])
604
+ public documents: Document[] = [];
605
+
606
+ @jsonProperty(File, null)
607
+ public photo: File | null = null;
608
+
609
+ @jsonIgnore()
610
+ public password: string = ''; // Will be excluded
611
+ }
612
+
613
+ // Create instance with nested data
614
+ const employee = new Employee();
615
+ employee.firstName = "John";
616
+ employee.lastName = "Doe";
617
+ employee.salary = 75000;
618
+
619
+ employee.homeAddress.street = "123 Main St";
620
+ employee.homeAddress.city = "New York";
621
+ employee.homeAddress.country = "USA";
622
+
623
+ const doc1 = new Document();
624
+ doc1.title = "Resume";
625
+ doc1.file = resumeFile; // File object
626
+
627
+ const doc2 = new Document();
628
+ doc2.title = "ID Card";
629
+ doc2.file = idCardFile; // File object
630
+
631
+ employee.documents = [doc1, doc2];
632
+ employee.photo = photoFile; // File object
633
+ employee.password = "secret123"; // Will be ignored
634
+
635
+ // Convert to FormData
636
+ const formData = employee.toFormData();
637
+
638
+ // Inspect the FormData
639
+ for (const [key, value] of formData.entries()) {
640
+ console.log(key, value);
641
+ }
207
642
  ```
208
643
 
209
- Naming strategies, custom names, ignoring and other decorators are supported during conversion.
644
+ **Resulting FormData structure:**
645
+
646
+ ```text
647
+ firstName: "John"
648
+ lastName: "Doe"
649
+ salary: "75000"
650
+ homeAddress.street: "123 Main St"
651
+ homeAddress.city: "New York"
652
+ homeAddress.country: "USA"
653
+ documents[0].title: "Resume"
654
+ documents[0].file: [File object - resume.pdf]
655
+ documents[1].title: "ID Card"
656
+ documents[1].file: [File object - id-card.jpg]
657
+ photo: [File object - photo.jpg]
658
+ ```
659
+
660
+ **Note:** The `password` property is excluded because of `@jsonIgnore()`.
661
+
662
+ ### With Custom Prefix
663
+
664
+ You can add a prefix to all form field names:
210
665
 
211
- Bonus
212
- ------
666
+ ```typescript
667
+ const formData = employee.toFormData("employee");
668
+
669
+ // Results in:
670
+ // employee.firstName: "John"
671
+ // employee.lastName: "Doe"
672
+ // employee.homeAddress.street: "123 Main St"
673
+ // etc.
674
+ ```
213
675
 
214
- Deep copy
676
+ ### Appending to Existing FormData
677
+
678
+ You can append to an existing FormData instance:
215
679
 
216
680
  ```typescript
217
- const newUser: User = new User().fromJSON(oldUser);
681
+ const existingFormData = new FormData();
682
+ existingFormData.append("companyId", "12345");
683
+ existingFormData.append("department", "Engineering");
684
+
685
+ // Append employee data
686
+ employee.toFormData("employee", existingFormData);
687
+
688
+ // existingFormData now contains:
689
+ // companyId: "12345"
690
+ // department: "Engineering"
691
+ // employee.firstName: "John"
692
+ // employee.lastName: "Doe"
693
+ // ... etc.
218
694
  ```
695
+
696
+ ### Special Type Handling
697
+
698
+ The FormData conversion handles different types intelligently:
699
+
700
+ | Type | Conversion |
701
+ |------|------------|
702
+ | `string`, `number`, `boolean` | Converted to string |
703
+ | `File` | Added as-is (native File object) |
704
+ | `Date` | Converted to ISO string |
705
+ | `null` | Skipped (not added to FormData) |
706
+ | `undefined` | Skipped (not added to FormData) |
707
+ | `Array` | Items added with `[index]` notation |
708
+ | `Object` | Properties added with dot notation |
709
+
710
+ **Note:** All decorators (`@jsonIgnore`, `@jsonName`, naming strategies) are respected during FormData conversion.
711
+
712
+ ## 💡 Additional Features
713
+
714
+ ### Deep Copy
715
+
716
+ Create a deep copy of an object by deserializing it:
717
+
718
+ ```typescript
719
+ const originalUser = new User();
720
+ originalUser.firstName = "John";
721
+ originalUser.age = 30;
722
+
723
+ const copiedUser: User = new User().fromJSON(originalUser);
724
+ // copiedUser is a completely separate instance with the same values
725
+ ```
726
+
727
+ ### Nested Objects
728
+
729
+ Handle complex object hierarchies with ease:
730
+
731
+ ```typescript
732
+ class Address extends Serializable {
733
+ @jsonProperty(String)
734
+ public street: string = '';
735
+
736
+ @jsonProperty(String)
737
+ public city: string = '';
738
+ }
739
+
740
+ class User extends Serializable {
741
+ @jsonProperty(String)
742
+ public name: string = '';
743
+
744
+ @jsonProperty(Address)
745
+ public address: Address = new Address();
746
+ }
747
+
748
+ const json = {
749
+ name: "John",
750
+ address: {
751
+ street: "123 Main St",
752
+ city: "New York"
753
+ }
754
+ };
755
+
756
+ const user = User.fromJSON(json);
757
+ console.log(user.address instanceof Address); // true
758
+ ```
759
+
760
+ ### Arrays of Objects
761
+
762
+ ```typescript
763
+ class Team extends Serializable {
764
+ @jsonProperty(String)
765
+ public name: string = '';
766
+
767
+ @jsonProperty([User])
768
+ public members: User[] = [];
769
+ }
770
+
771
+ const json = {
772
+ name: "Dev Team",
773
+ members: [
774
+ { firstName: "John", lastName: "Doe", age: 30 },
775
+ { firstName: "Jane", lastName: "Smith", age: 28 }
776
+ ]
777
+ };
778
+
779
+ const team = Team.fromJSON(json);
780
+ console.log(team.members[0] instanceof User); // true
781
+ ```
782
+
783
+ ## 📚 API Reference
784
+
785
+ ### Serializable Class Methods
786
+
787
+ #### Static Methods
788
+
789
+ - **`fromJSON<T>(json: object, settings?: Partial<SerializationSettings>): T`**
790
+
791
+ Creates a new instance and deserializes JSON data into it.
792
+
793
+ - **`fromString<T>(str: string, settings?: Partial<SerializationSettings>): T`**
794
+
795
+ Parses a JSON string and deserializes it into a new instance.
796
+
797
+ #### Instance Methods
798
+
799
+ - **`fromJSON(json: object, settings?: Partial<SerializationSettings>): this`**
800
+
801
+ Populates the current instance with data from JSON.
802
+
803
+ - **`fromString(str: string, settings?: Partial<SerializationSettings>): this`**
804
+
805
+ Parses a JSON string and populates the current instance.
806
+
807
+ - **`toJSON(): Record<string, unknown>`**
808
+
809
+ Serializes the instance to a plain JavaScript object.
810
+
811
+ - **`toString(): string`**
812
+
813
+ Serializes the instance to a JSON string.
814
+
815
+ - **`toFormData(formPrefix?: string, formData?: FormData): FormData`**
816
+
817
+ Converts the instance to FormData for multipart requests.
818
+
819
+ - **`onWrongType(prop: string, message: string, value: unknown): void`**
820
+
821
+ Error handler for type mismatches. Override to customize error behavior.
822
+
823
+ ### Standalone Functions
824
+
825
+ - **`fromJSON<T>(obj: T, json: object, settings?: Partial<SerializationSettings>): T`**
826
+
827
+ Deserializes JSON into an existing object instance.
828
+
829
+ - **`toJSON(obj: Serializable | object): Record<string, unknown>`**
830
+
831
+ Serializes an object to a plain JavaScript object.
832
+
833
+ - **`classToFormData(obj: object, formPrefix?: string, formData?: FormData): FormData`**
834
+
835
+ Converts an object to FormData format.
836
+
837
+ ### Available Naming Strategies
838
+
839
+ - `SnakeCaseNamingStrategy` - Converts to snake_case
840
+ - `CamelCaseNamingStrategy` - Converts to camelCase
841
+ - `PascalCaseNamingStrategy` - Converts to PascalCase
842
+ - `KebabCaseNamingStrategy` - Converts to kebab-case
843
+
844
+ ## 🤝 Contributing
845
+
846
+ Contributions are welcome! Please feel free to submit a Pull Request.
847
+
848
+ ## 📄 License
849
+
850
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
851
+
852
+ ## 🙏 Acknowledgments
853
+
854
+ Special thanks to all contributors and users of this library.