From d0dc058b03c135846ce4c8e7dd5953061e2f7a8c Mon Sep 17 00:00:00 2001 From: Jan Halfar Date: Wed, 3 May 2023 09:54:56 +0200 Subject: [PATCH] feat: extend gtsrpc value object docs --- .../service-interfaces/value-objects.md | 216 ++++++++++++------ 1 file changed, 150 insertions(+), 66 deletions(-) diff --git a/foomo/docs/projects/gotsrpc/service-interfaces/value-objects.md b/foomo/docs/projects/gotsrpc/service-interfaces/value-objects.md index 0c1ce7f..df6447c 100644 --- a/foomo/docs/projects/gotsrpc/service-interfaces/value-objects.md +++ b/foomo/docs/projects/gotsrpc/service-interfaces/value-objects.md @@ -2,12 +2,17 @@ sidebar_position: 1 toc_max_heading_level: 5 --- + # Value Objects Typically value objects will be serialized / marshalled as JSON. Please refer to this documentation: [https://pkg.go.dev/encoding/json#Marshal](https://pkg.go.dev/encoding/json#Marshal) +:::note +This is just a few basic examples, that show the basics of mapping Go types to idiomatic TypeScript types. +::: + ## Scalar types ### Supported in Go and TypeScript @@ -25,13 +30,11 @@ Typically value objects will be serialized / marshalled as JSON. Please refer to ### Type Aliases -Go -```go +```go title="Go" type Greeting string ``` -TypeScript -```typescript +```typescript title="TypeScript" type Greeting = string; ``` @@ -39,8 +42,7 @@ type Greeting = string; Go does not support enumerations, but `gotsrpc` will translate constants to TypeScripts enums: -Go -```go +```go title="Go" type Pet string const ( @@ -58,134 +60,216 @@ const ( ) ``` -TypeScript -```typescript +```typescript title="TypeScript" export enum Pet { - Cat = "cat", - Dog = "dog", - Fish = "fish", + Cat = "cat", + Dog = "dog", + Fish = "fish", } export enum SeatCount { - FiveSeats = 5, - SevenSeats = 7, - TwoSeats = 2, + FiveSeats = 5, + SevenSeats = 7, + TwoSeats = 2, } ``` - -## Structs / Interfaces - -```go -type Car struct { - -} -``` - -```typescript -interface Car { - -} -``` - ## Slices Slices are nilable in Go, thus they can be null in TypeScript. They translate to `Array|null` in TypeScript. + ### Scalar types -```go +```go title="Go" []string []int // other numeric types []bool ``` -```typescript -Array|null -Array|null +```typescript title="TypeScript" +Array | null; +Array | null; // all numeric types are numbers -Array|null +Array | null; ``` ### Other slice type examples +#### Structs -#### structs -```go +```go title="Go" []Car []*Car ``` -```typescript -Array|null -Array|null +```typescript title="TypeScript" +Array | null; +Array | null; ``` -#### nested slices -```go + +#### Nested slices + +```go title="Go" [][]string [][]int // ... ``` -```typescript -Array|null>|null -Array|null>|null +```typescript title="TypeScript" +Array | null> | null; +Array | null> | null; // ... ``` - - ## Maps / Records -Like slices Go maps are nilable. They translate to `Record|null` in TypeScript. +Like slices Go maps are nilable. They translate to `Record|null` in TypeScript. +### Scalars -### scalars - -```go +```go title="Go" map[string]string ``` -```typescript -Record|null +```typescript title="TypeScript" +Record | null; ``` -### structs +### Structs -```go +```go title="Go" map[string]*Car ``` -```typescript -Record|null +```typescript title="TypeScript" +Record | null; ``` -### slices +### Slices -```go +```go title="Go" map[string][]*Car ``` -```typescript -Record|null>|null +```typescript title="TypeScript" +Record | null> | null; ``` -## custom map types +## Map types Go and TypeScript support map / Record types: -:::note +:::tip Scalar types / type aliases are of particular value when using maps, because they can add strong semantics: ::: -```go +```go title="Go" type CarDirectory map[ProductID]*Car ``` -```typescript -type CarDirectory = Record|null +```typescript title="TypeScript" +type CarDirectory = Record | null; ``` +## Nested map types +```go title="Go" +type BrandID string +type BrandCarDirectory map[BrandID]map[ProductID]*Car +// or +type BrandCarDirectory map[BrandID]CarDirectory +``` +```typescript title="TypeScript" +type BrandID = string; +type BrandCarDirectory = Record< + BrandID, + Record | null +> | null; +// or +type BrandCarDirectory = Record | null; +``` +## Structs / Interfaces + +Arbitrary Types can be composed in structs. + +### Field names + +Naming conventions are different between Go and TypeScript. In order to bridge the gap between Go and TypeScript Go struct fields can be [annotated with tags](https://pkg.go.dev/encoding/json#Marshal). In this way idiomatic naming of fields can be can be provided for both languages and the translation will be automatic. + +#### Default Go => TypeScript + +Without json tags TypeScript field names will be like in Go, which is not idiomatic for TypeScript. + +```go title="Go" +type Car struct { + GoCase string + CamelCase string + SnakeCase string +} +``` + +```typescript title="TypeScript" +interface Car { + GoCase:string; + CamelCase:string; + SnakeCase:string; +} +``` + +#### Idiomatic field names + +Json tags allow controlling the name in TypeScript. + +```go title="Go" +type Car struct { + CamelCase string `json:"camelCase"` + SnakeCase string `json:"snake_case"` +} +``` + +```typescript title="TypeScript" +interface Car { + camelCase:string; + snake_case:string; +} +``` + +### Optional and nullable fields + +```go title="Go" +type Basic struct { + Value string `json:"value"` + OptionalValue string `json:"optionalValue,omitempty"` + NullableValue *string `json:"nullableValue"` +} +``` + +```typescript title="TypeScript" +type Basic interface { + value:string; + optionalValue?:string; + nullableValue:string|null; +} +``` + +### Hiding values from the client + +The Go json tag ``` `json:"-"` ``` on a struct allows it to: + +- hide fields from clients +- prevents clients from setting them in JSON Unmarshalling + +```go title="Go" +type Basic struct { + Value string `json:"value"` + Secret string `json:"-"` +} +``` + +```typescript title="TypeScript" +type Basic interface { + value:string; +} +``` -### nested maps \ No newline at end of file