Skip to content

--strictOptions

By default, Fickl and Fable erase an option: Some x is x and None is undefined. That is fast and reads naturally from JavaScript, but for a type that can itself be null, Some null and None become the same value. --strictOptions keeps them apart.

Without the flag

Some null is None, so the second case is never reached:

let describe (name: string option) =
    match name with
    | None -> "none"
    | Some null -> "some null"
    | Some n -> n

let result = describe (Some null)
import { defaultOf } from "@fable-org/fable-library-js/Util.js";

export function describe(name) {
    if (name != null) {
        if (name === defaultOf()) {
            return "some null";
        }
        else {
            const n = name;
            return n;
        }
    }
    else {
        return "none";
    }
}

export const result = describe(null);

With the flag

An option of a type that can be null is built with some and read with value, so Some null stays Some, as on .NET. It is built the same way at concrete and generic call sites.

let describe (name: string option) =
    match name with
    | None -> "none"
    | Some null -> "some null"
    | Some n -> n

let result = describe (Some null)
import { some, value } from "@fable-org/fable-library-js/Option.js";
import { defaultOf } from "@fable-org/fable-library-js/Util.js";

export function describe(name) {
    if (name != null) {
        if (value(name) === defaultOf()) {
            return "some null";
        }
        else {
            const n = value(name);
            return n;
        }
    }
    else {
        return "none";
    }
}

export const result = describe(some(null));

Options of types that cannot be null, such as int option, are erased either way.

For interop

A value option, voption, stays erased with or without the flag. Use it for values that cross into JavaScript, where undefined is the expected way to say "nothing".

Edit this page