Catch errors at compile time

Static typing is a language feature that identifies type mismatch errors at compile time and benefits your development work by preventing the kind of bugs that can be hard to diagnose and fix at runtime.

Type checking by example

For comparison, this example uses the CoffeeBean collection to show how Fauna handles queries with type checking enabled and disabled.

  1. Log in to your Fauna Dashboard and create or select a database.

  2. Create a CoffeeBean document that you can run queries against to see how type checking works:

    CoffeeBean.create({
        "Species": "Robusta",
        "Owner": "cafe politico",
        "Country_of_Origin": "Vietnam",
        "Harvest_Year": 2013,
        "Quality_Parameters": {
          "Aroma": 6.75,
          "Flavor": 6.67,
          "Balance": 6.83
        },
        "Altitude": {
          "unit_of_measurement": "m",
          "low": "",
          "high": "",
          "mean": ""
        }
    })
    {
      id: "367800976030040132",
      coll: CoffeeBean,
      ts: Time("2023-06-17T16:59:54.390Z"),
      Species: "Robusta",
      Owner: "cafe politico",
        ... elided ...
    }
  3. With type checking disabled, update the Owner field using the document ID:

    CoffeeBean.byId("367800976030040132").update(
      { Owner: "Healthy Grounds, Inc." }
    )
    {
      id: "367800976030040132",
      coll: CoffeeBean,
      ts: Time("2023-06-17T17:01:24.570Z"),
      Species: "Robusta",
      Owner: "Healthy Grounds, Inc.",
        .. elided ...
    }

    You should see that the Owner field changed.

  4. Enable type checking by clicking the T button in the menu bar.

  5. With type checking enabled, update the document using the same command to restore the original Owner:

    CoffeeBean.byId("367800976030040132").update(
      { Owner: "cafe politico" }
    )
    QueryCheckError
    
    error: Type `Null` does not have field `update`
    at *query*:1:39
      |
    1 | CoffeeBean.byId("367800976030040132").update(
      |                                       ^^^^^^
      |
    hint: Use the ! or ?. operator to handle the null case
      |
    1 | CoffeeBean.byId("367800976030040132")!.update(
      |                                      +
      |

    You should see a QueryCheckError error, which indicates that the query failed compile-time type checking.

    The Type `Null` does not have field `update` error occurs because the CoffeeBean.byId("367800976030040132") query can return a null value if a CoffeeBean document with that ID doesn’t exist. The type checker knows that the query can return a Document type or a Null type. Because Null types don’t have fields, the static type check fails.

    If there are multiple type errors in a query, all errors are returned in the response. Error reporting doesn’t stop at the first error. This allows you to address all errors in a query without rerunning the query to debug each error independently.

    The error response also includes a hint about how to resolve the error. In this example, the compiler hints that you should Use the ! or ?. operator to handle the null case. See the reference documentation for more about the non-null assertion postfix and optional chaining operators.

  6. Finally, follow the error notification hint and add the non-null assertion postfix operator to successfully run the same query:

CoffeeBean.byId("367800976030040132")!.update(
  { Owner: "cafe politico" }
)
{
  id: "367800976030040132",
  coll: CoffeeBean,
  ts: Time("2023-06-17T17:07:29.885Z"),
  Species: "Robusta",
  Owner: "cafe politico",
    ... elided ...
}

Enable static typing

You can enable static typing using one of the following options:

  • In the Dashboard.

  • In the driver.

  • In the database configuration.

Enable static typing for a database

Enabled type checking for a database using the FQL update() command to update the database definition, as shown in this example:

Database.byName( "demo" ).update( { typechecked: true } )

The typecheck property set using the driver or query option overrides the database setting.

Enable static typing in the driver

Drivers for the supported languages can be configured to enable type checking at two levels:

  • Enable type checking of all queries sent by the driver by setting the typecheck property to true in the driver client configuration.

  • Enable type checking per-query by setting the typecheck property to true in the query options field:

    CoffeeBean.all().first()!.update({ typecheck: true })
    {
      id: "366190504817197124",
      coll: CoffeeBean,
      ... elided ...
      typecheck: true
    }

 

If type checking is enabled in the driver or per query, type checking must also be enabled in the database.

UDF definition type checking

Type checking can’t be disabled for user-defined function (UDF) definitions. This example shows how you can use the UDF definition signature field to explicitly type the UDF when you create it:

Function.create({
  name: "TypeTest",
  signature: "(x: Number, y: Number) => Number",
  body: "(x, y) => x + y "
})
{
  name: "TypeTest",
  coll: Function,
  ts: Time("2023-06-15T16:26:49.410Z"),
  body: "(x, y) => x + y ",
  signature: "(x: Number, y: Number) => Number"
}

UDF type checking errors result in a QueryRuntimeError runtime error, which differs from the usual compile-time error notification generated by query type checking errors.

Learn more

See the Static typing reference documentation for more detailed information about type checking.

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!