Skip to content

v0.13.0

Pre-release
Pre-release
Compare
Choose a tag to compare
@github-actions github-actions released this 20 Feb 21:03
· 50 commits to main since this release
v0.13.0
d900821

This release introduces several breaking changes that widely improve the usage of unions and flat unions.
Union tags now use type alias as value.
--use-flat-union is removed in favor of --use-primitive-flat-union and --use-struct-flat-union.
Union flattening now uses a "best-effort approach".

  • BREAKING CHANGES: use strings tags for union of aliases

    bare-ts outputs now string tags for unions of aliases.
    You can obtain the previous behavior with the option --use-int-tag.

    The following schema ...

    type Person struct { name: str }
    type Organization struct { name: str }
    type Contact union { Person | Organization }
    

    ... generates the following types:

    export type Person = { readonly name: string }
    export type Organization = { readonly name: string }
    export type Contact =
        | { tag: "Person"; val: Person }
        | { tag: "Organization"; val: Organization }

    This makes code more readable and allow assigning between compatible unions.

    Using the option --use-int-tag, you obtain the previous output:

    export type Person = { readonly name: string }
    export type Organization = { readonly name: string }
    export type Contact =
        | { tag: 0; val: Person }
        | { tag: 1; val: Organization }
  • BREAKING CHANGES: use type alias as tag's value for flat unions of structs

    bare-ts allows flat unions of aliased structs.
    Previously, it used the type alias in underscore_case as tag's value.
    Now, it uses the type alias in its original case.

    For instance, the following union:

    type BoxedU32 struct { val: u32 }
    type BoxedStr struct { val: str }
    type Boxed union { BoxedU32 | BoxedStr }
    

    can be flatten (under --use-flat-union) to:

    export type BoxedU32 = {
    -   readonly tag: "BOXED_U32", // Previous output
    +   readonly tag: "BoxedU32", // New output
        readonly val: u32,
    }
    
    export type BoxedStr = {
    -   readonly tag: "BOXED_STR", // Previous output
    +   readonly tag: "BoxedStr", // New output
        readonly val: string,
    }
    
    export type Boxed = BoxedU32 | BoxedStr
  • BREAKING CHANGES: split --use-flat-union into --use-primitive-flat-union and --use-struct-flat-union

    Use --use-primitive-flat-union and --use-struct-flat-union instead of --use-flat-union.

  • Flatten unions when possible under --use-primitive-flat-union and --use-struct-flat-union

    bare-ts is able to flatten unions that consist of:

    1. basic types (bool, u8, str, ...) that have distinct typeof values
    2. aliased structs
    3. (anonymous) structs

    Previously, use-flat-union required that all unions be flattened.
    This avoided introducing a "best-effort approach".
    However, this was too restrictive.
    A "best-effort approach" seems acceptable since it is opted in.
    Now, bare-ts attempts to flatten a union and falls back to a tagged union.

    Under --use-struct-flat-union, the following schema...

    type A union { bool | f64 | str }
    type B union { f64 | i32 }
    

    ...compiles to the following types:

    type A = boolean | number | string
    type B = { tag: 0; val: number } | { tag: 1; val: number }

    Note that B is not flatten because f64 and i32 have the same typeof value (number).

    Under --use-struct-flat-union, the following schema...

    type X struct { ... }
    type Y struct { ... }
    type XY union { X | Y }
    type Z Y
    type XZ union { X | Z }
    type Anonymous union { struct { ... } | struct { ... } }
    

    ...compiles to the following types:

    type X = { tag: "X", ... }
    type Y = { tag: "Y", ... }
    type XY = X | Y
    type Z = Y
    type XZ = { tag: "X", val: X } | { tag: "Z", val: "Z" }
    type Anonymous = { tag: 0, ... } | { tag: 1, ... }

    Note that the union XZ is not flatten, because one of the elements is not a struct or an aliased struct.
    Indeed, Z is an aliased alias.

  • Support flat unions of aliased structs and anonymous structs

    Under the option --use-struct-flat-union, the following schema...

    type Person struct { name: str }
    type Entity union {
        | Person
        # Anonymous entity
        | struct { name: str }
    }
    

    ...compiles to the following types

    export type Person = {
        readonly tag: "Person"
        readonly name: string
    }
    export type Entity =
        | Person
        | {
              readonly tag: 1
              readonly name: string
          }

    We introduce this change for consistency purpose.
    You should avoid mixing aliased structs with anonymous structs