or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdbuiltins.mddescriptors.mdencoding.mdindex.mdmodules.mdserializers.md

serializers.mddocs/

0

# Core Serializers

1

2

Complete reference for the KSerializer interface and core serialization strategies in kotlinx.serialization-core-js.

3

4

## Core Interfaces

5

6

### KSerializer<T>

7

8

The primary interface that combines serialization and deserialization capabilities.

9

10

```kotlin

11

interface KSerializer<T> : SerializationStrategy<T>, DeserializationStrategy<T> {

12

val descriptor: SerialDescriptor

13

}

14

```

15

{ .api }

16

17

**Usage:**

18

19

```javascript

20

// Get serializer for a class

21

const userSerializer = User.serializer();

22

23

// Use with any format

24

const json = format.encodeToString(userSerializer, user);

25

const decoded = format.decodeFromString(userSerializer, json);

26

27

// Access descriptor

28

console.log(userSerializer.descriptor.serialName); // "User"

29

```

30

31

### SerializationStrategy<T>

32

33

Interface for types that can be serialized to a format.

34

35

```kotlin

36

interface SerializationStrategy<T> {

37

val descriptor: SerialDescriptor

38

fun serialize(encoder: Encoder, value: T)

39

}

40

```

41

{ .api }

42

43

**Usage:**

44

45

```javascript

46

class CustomSerializationStrategy {

47

constructor(descriptor) {

48

this.descriptor = descriptor;

49

}

50

51

serialize(encoder, value) {

52

// Custom serialization logic

53

encoder.encodeString(value.toString());

54

}

55

}

56

```

57

58

### DeserializationStrategy<T>

59

60

Interface for types that can be deserialized from a format.

61

62

```kotlin

63

interface DeserializationStrategy<T> {

64

val descriptor: SerialDescriptor

65

fun deserialize(decoder: Decoder): T

66

}

67

```

68

{ .api }

69

70

**Usage:**

71

72

```javascript

73

class CustomDeserializationStrategy {

74

constructor(descriptor) {

75

this.descriptor = descriptor;

76

}

77

78

deserialize(decoder) {

79

// Custom deserialization logic

80

const str = decoder.decodeString();

81

return parseCustomFormat(str);

82

}

83

}

84

```

85

86

## Serializer Factory Functions

87

88

### serializer<T>()

89

90

Retrieves a serializer for a reified type T.

91

92

```kotlin

93

inline fun <reified T> serializer(): KSerializer<T>

94

```

95

{ .api }

96

97

**Usage:**

98

99

```javascript

100

// For basic types

101

const stringSerializer = serializer<String>();

102

const intSerializer = serializer<Int>();

103

104

// For collections with type parameters

105

const listSerializer = serializer<List<String>>();

106

const mapSerializer = serializer<Map<String, Int>>();

107

108

// For custom classes

109

const userSerializer = serializer<User>();

110

```

111

112

### SerializersModule.serializer<T>()

113

114

Retrieves a serializer with contextual lookup from a module.

115

116

```kotlin

117

inline fun <reified T> SerializersModule.serializer(): KSerializer<T>

118

```

119

{ .api }

120

121

**Usage:**

122

123

```javascript

124

const module = SerializersModule {

125

contextual(Date, CustomDateSerializer)

126

};

127

128

// Gets contextual serializer if available, otherwise default

129

const dateSerializer = module.serializer<Date>();

130

```

131

132

### serializer(type: KType)

133

134

Creates a serializer for a given KType (includes nullability and generics).

135

136

```kotlin

137

fun serializer(type: KType): KSerializer<Any?>

138

```

139

{ .api }

140

141

**Usage:**

142

143

```javascript

144

import { typeOf } from 'kotlin-stdlib-js';

145

146

// For nullable types

147

const nullableStringType = typeOf<String?>();

148

const nullableStringSerializer = serializer(nullableStringType);

149

150

// For generic types

151

const listOfStringType = typeOf<List<String>>();

152

const listSerializer = serializer(listOfStringType);

153

```

154

155

### serializer(kClass, typeArgs, isNullable)

156

157

Creates a serializer for a KClass with type arguments (Experimental).

158

159

```kotlin

160

@ExperimentalSerializationApi

161

fun serializer(

162

kClass: KClass<*>,

163

typeArgumentsSerializers: Array<KSerializer<*>>,

164

isNullable: Boolean

165

): KSerializer<Any?>

166

```

167

{ .api }

168

169

**Usage:**

170

171

```javascript

172

// Create List<User> serializer

173

const userClass = User::class;

174

const userSerializer = serializer<User>();

175

const listUserSerializer = serializer(

176

List::class,

177

[userSerializer],

178

false // not nullable

179

);

180

```

181

182

### serializerOrNull(type: KType)

183

184

Creates a serializer for KType or returns null if unavailable.

185

186

```kotlin

187

fun serializerOrNull(type: KType): KSerializer<Any?>?

188

```

189

{ .api }

190

191

**Usage:**

192

193

```javascript

194

const type = typeOf<SomeUnknownClass>();

195

const serializer = serializerOrNull(type);

196

197

if (serializer !== null) {

198

// Safe to use serializer

199

const json = format.encodeToString(serializer, value);

200

} else {

201

console.log("No serializer available for type");

202

}

203

```

204

205

## Special Serializers

206

207

### ContextualSerializer<T>

208

209

Serializer that delegates to runtime lookup in SerializersModule (Experimental).

210

211

```kotlin

212

@ExperimentalSerializationApi

213

class ContextualSerializer<T : Any>(

214

private val serializableClass: KClass<T>,

215

private val fallbackSerializer: KSerializer<T>? = null,

216

private val typeArgumentsSerializers: Array<KSerializer<*>> = emptyArray()

217

) : KSerializer<T>

218

```

219

{ .api }

220

221

**Usage:**

222

223

```javascript

224

// Create contextual serializer for Date

225

const dateContextualSerializer = new ContextualSerializer(

226

Date::class,

227

DefaultDateSerializer, // fallback

228

[] // no type arguments

229

);

230

231

// Use in SerializersModule

232

const module = SerializersModule {

233

contextual(Date::class, CustomDateSerializer)

234

};

235

236

// When used with module, CustomDateSerializer will be used

237

// When used without module, DefaultDateSerializer will be used

238

```

239

240

### PolymorphicSerializer<T>

241

242

Serializer for polymorphic serialization of class hierarchies.

243

244

```kotlin

245

class PolymorphicSerializer<T : Any>(private val baseClass: KClass<T>) : KSerializer<T>

246

```

247

{ .api }

248

249

**Usage:**

250

251

```javascript

252

// Create polymorphic serializer for base class

253

const shapeSerializer = new PolymorphicSerializer(Shape::class);

254

255

// Configure subclasses in module

256

const module = SerializersModule {

257

polymorphic(Shape::class) {

258

subclass(Circle::class)

259

subclass(Rectangle::class)

260

subclass(Triangle::class)

261

}

262

};

263

264

// Use with format configured with the module

265

const json = format.encodeToString(shapeSerializer, circleInstance);

266

// Output includes type discriminator: {"type":"Circle","radius":5}

267

```

268

269

### SealedClassSerializer<T>

270

271

Internal serializer for sealed classes (handled automatically).

272

273

```kotlin

274

@InternalSerializationApi

275

class SealedClassSerializer<T : Any>(

276

private val serialName: String,

277

private val baseClass: KClass<T>,

278

private val subclassSerializers: Array<KSerializer<out T>>,

279

private val subclassNames: Array<String>

280

) : KSerializer<T>

281

```

282

{ .api }

283

284

**Usage:**

285

286

```javascript

287

// Sealed class (automatically gets SealedClassSerializer)

288

@Serializable

289

sealed class Result {

290

@Serializable

291

static class Success extends Result {

292

constructor(data) {

293

super();

294

this.data = data;

295

}

296

}

297

298

@Serializable

299

static class Error extends Result {

300

constructor(message) {

301

super();

302

this.message = message;

303

}

304

}

305

}

306

307

// Automatically uses SealedClassSerializer

308

const resultSerializer = Result.serializer();

309

```

310

311

## Companion Object Serializers

312

313

Many standard types provide serializers through companion objects:

314

315

### Primitive Type Serializers

316

317

```kotlin

318

// Companion object extensions

319

val Char.Companion.serializer: KSerializer<Char>

320

val Byte.Companion.serializer: KSerializer<Byte>

321

val Short.Companion.serializer: KSerializer<Short>

322

val Int.Companion.serializer: KSerializer<Int>

323

val Long.Companion.serializer: KSerializer<Long>

324

val Float.Companion.serializer: KSerializer<Float>

325

val Double.Companion.serializer: KSerializer<Double>

326

val Boolean.Companion.serializer: KSerializer<Boolean>

327

val String.Companion.serializer: KSerializer<String>

328

```

329

{ .api }

330

331

**Usage:**

332

333

```javascript

334

// Access via companion objects

335

const charSer = Char.serializer();

336

const byteSer = Byte.serializer();

337

const shortSer = Short.serializer();

338

const intSer = Int.serializer();

339

const longSer = Long.serializer();

340

const floatSer = Float.serializer();

341

const doubleSer = Double.serializer();

342

const booleanSer = Boolean.serializer();

343

const stringSer = String.serializer();

344

```

345

346

### Special Type Serializers

347

348

```kotlin

349

val Unit.serializer: KSerializer<Unit>

350

val UInt.Companion.serializer: KSerializer<UInt>

351

val ULong.Companion.serializer: KSerializer<ULong>

352

val UByte.Companion.serializer: KSerializer<UByte>

353

val UShort.Companion.serializer: KSerializer<UShort>

354

val Duration.Companion.serializer: KSerializer<Duration>

355

```

356

{ .api }

357

358

**Usage:**

359

360

```javascript

361

const unitSer = Unit.serializer();

362

const uintSer = UInt.serializer();

363

const ulongSer = ULong.serializer();

364

const ubyteSer = UByte.serializer();

365

const ushortSer = UShort.serializer();

366

const durationSer = Duration.serializer();

367

```

368

369

### Experimental Serializers

370

371

```kotlin

372

@ExperimentalSerializationApi

373

val Instant.Companion.serializer: KSerializer<Instant>

374

375

@ExperimentalSerializationApi

376

val Uuid.Companion.serializer: KSerializer<Uuid>

377

```

378

{ .api }

379

380

**Usage:**

381

382

```javascript

383

// Experimental APIs (may change)

384

const instantSer = Instant.serializer();

385

const uuidSer = Uuid.serializer();

386

```

387

388

## Nullable Serializers

389

390

### .nullable Property

391

392

All serializers can be made nullable using the `.nullable` property:

393

394

```kotlin

395

val KSerializer<T>.nullable: KSerializer<T?>

396

```

397

{ .api }

398

399

**Usage:**

400

401

```javascript

402

// Make any serializer nullable

403

const stringSerializer = String.serializer();

404

const nullableStringSerializer = stringSerializer.nullable;

405

406

// Works with complex types too

407

const userSerializer = User.serializer();

408

const nullableUserSerializer = userSerializer.nullable;

409

410

// Use with collections

411

const listSerializer = ListSerializer(String.serializer());

412

const nullableListSerializer = listSerializer.nullable;

413

```

414

415

## Custom Serializer Implementation

416

417

### Basic Custom Serializer

418

419

```javascript

420

class CustomUserSerializer {

421

constructor() {

422

this.descriptor = buildClassSerialDescriptor("CustomUser") {

423

element("fullName", String.serializer().descriptor)

424

element("birthYear", Int.serializer().descriptor)

425

};

426

}

427

428

serialize(encoder, value) {

429

const composite = encoder.beginStructure(this.descriptor);

430

composite.encodeStringElement(this.descriptor, 0, `${value.firstName} ${value.lastName}`);

431

composite.encodeIntElement(this.descriptor, 1, new Date().getFullYear() - value.age);

432

composite.endStructure(this.descriptor);

433

}

434

435

deserialize(decoder) {

436

const composite = decoder.beginStructure(this.descriptor);

437

438

let fullName = "";

439

let birthYear = 0;

440

441

while (true) {

442

const index = composite.decodeElementIndex(this.descriptor);

443

if (index === CompositeDecoder.DECODE_DONE) break;

444

445

switch (index) {

446

case 0:

447

fullName = composite.decodeStringElement(this.descriptor, 0);

448

break;

449

case 1:

450

birthYear = composite.decodeIntElement(this.descriptor, 1);

451

break;

452

default:

453

throw new SerializationException(`Unexpected index: ${index}`);

454

}

455

}

456

457

composite.endStructure(this.descriptor);

458

459

const parts = fullName.split(' ');

460

const age = new Date().getFullYear() - birthYear;

461

return new User(parts[0], parts[1], age);

462

}

463

}

464

```

465

466

### Using Custom Serializers

467

468

```javascript

469

// Register with @Serializable

470

@Serializable(CustomUserSerializer::class)

471

class User {

472

constructor(firstName, lastName, age) {

473

this.firstName = firstName;

474

this.lastName = lastName;

475

this.age = age;

476

}

477

}

478

479

// Or use directly

480

const customSerializer = new CustomUserSerializer();

481

const json = format.encodeToString(customSerializer, user);

482

const decoded = format.decodeFromString(customSerializer, json);

483

```

484

485

## Error Handling

486

487

Serializers can throw specific exceptions:

488

489

```javascript

490

class ValidatingSerializer {

491

serialize(encoder, value) {

492

if (!this.isValid(value)) {

493

throw new SerializationException("Invalid value for serialization");

494

}

495

// ... serialization logic

496

}

497

498

deserialize(decoder) {

499

const result = /* ... deserialization logic */;

500

501

if (!this.isValid(result)) {

502

throw new SerializationException("Deserialized value failed validation");

503

}

504

505

return result;

506

}

507

508

isValid(value) {

509

// Validation logic

510

return value !== null && value !== undefined;

511

}

512

}

513

```

514

515

## TypeScript Integration

516

517

Serializers maintain full type safety in TypeScript:

518

519

```typescript

520

// Typed serializer creation

521

const userSerializer: KSerializer<User> = User.serializer();

522

const listSerializer: KSerializer<Array<User>> = ListSerializer(userSerializer);

523

524

// Generic serializer functions

525

function serializeList<T>(serializer: KSerializer<T>, items: T[]): string {

526

const listSer = ListSerializer(serializer);

527

return format.encodeToString(listSer, items);

528

}

529

530

// Type-safe usage

531

const users: User[] = [new User("John", 30), new User("Jane", 25)];

532

const json: string = serializeList(User.serializer(), users);

533

```

534

535

The serializer system provides the foundation for all serialization operations while maintaining type safety and performance across different formats and use cases.