Options
All
  • Public
  • Public/Protected
  • All
Menu

Types for Salesforce CLI development

What is this?

This is a simple TypeScript-oriented library developed for use in Salesforce CLI libraries, applications, and plugins consisting of two parts:

  1. A collection of commonly desired types.
  2. A collection of type-narrowing convenience functions for writing concise type-guards.

Why did we create it?

We were interested in enabling strict compiler settings in TypeScript. Among the sub-settings that comprise strict mode are "strict null checks", "strict property initialization", and "no implicit any". These settings have the potential to increase code quality substantially, reducing the frequency of certain classes of runtime errors typical in JavaScript applications. They also encourage the writing of clearer code, which helps teams work together and more rapidly onboard new hires.

Of course, stricter compiler settings require developers to write more type-safe code -- or to work around the compiler's insistence on type-safety. Often this stricter style leads to more verbose code in the way of type declarations and type guards, and can require new and occasionally unfamiliar patterns to accomplish without subverting the compiler's enforcement of the type system (typically via the use of type assertions).

TypeScript provides both syntax and built-in types designed to help write well-typed code, but we can be more terse and concise by employing additional types and type-oriented utilities. That's where this library comes in.

How will it help me?

This library has its roots in solving the problem of how to handle untyped JSON data in a type-safe way. It was born when we added some basic type declarations to replace the unsafe any type as a stand-in for JSON data with a type that could capture the range of data available in any JSON construct. This yielded the AnyJson type, which is effectively a union of all primitive and collection JSON values. The type alone was not enough to make for convenient, type-guarded handling of JSON data, however. TypeScript supports a very elegant system of control flow analysis that will narrow the type of a variable in code after the compiler can prove the set of possible types of the variable has been reduced. Using type guards in your code improves its runtime type safety characteristics, makes it more readable, and provides richer typing information for IDEs. Type guards are implemented as conditional statements, however, and can quickly become noisy and make what was once terse JavaScript code expand into several lines of type checking. This library aimed to simplify the experience of reducing the amount of type guards needed to process a typed-JSON data structure by providing several convenience functions that help extract well-typed data from such JSON structures.

For example, look at the following typical untyped JSON processing in JavaScript:

// Concise, but not at all null-safe or type-safe; often made to be at least null-safe using lodash fns
JSON.parse(response.body).results.forEach(item => db.save(item.id, item));

Then a safe version in bare TypeScript using type guards:

const json = JSON.parse(response.body);
// Type of json -> `any`, but will not be undefined or JSON.parse would throw
if (json === null && typeof json !== 'object') throw new Error('Unexpected json data type');
let results = json.results;
// Type of results -> `any`
if (!Array.isArray(results)) results = [];
// Type of results -> `any[]`
results.forEach(item => {
// Type of item -> `any`
    const id = item.id;
    // Type of id -> `any`
    if (typeof id !== 'string') throw new Error('Unexpected item id data type');
    // Type of id -> `string`
    db.save(id, item);
});

While that's pretty safe, it's also a mess to read and write. That's why this library is here to help!

const json = ensureJsonMap(JSON.parse(response.body));
// Type of json -> `JsonMap` or raises an error
const results = asJsonArray(json.results, []);
// Type of results -> `JsonArray` or uses the default of `[]`
results.forEach(item => {
    // Type of item -> `AnyJson`
    record = ensureJsonMap(record);
    db.save(ensureString(record.id), record);
});

Removing the comments, we can shorten the above somewhat to achieve something not much more complex than the original example, but with robust type and null checking implemented:

asJsonArray(ensureJsonMap(JSON.parse(response.body)).results, []).forEach(item => {
    const record = ensureJsonMap(item);
    db.save(ensureString(record.id), record);
});

The ensure* functions are used in this example since they will raise an error when the value being checked either does not exist or does not match the expected type. Additionally, and perhaps more importantly, the generic any and AnyJson types get progressively narrowed when using these functions to more specific types. Of course, you don't always want to raise an error when these conditions are not met, so alternative forms exist for each of the JSON data types that allow the types to be tested and narrowed -- see the is* and as* variants in the API documentation for testing and narrowing capabilities without additionally raising errors.

Beyond JSON

After a few iterations of working on the JSON support types and utilities, it became apparent that we needed other non-JSON types and functions that provide similar capabilities. Rather than create a new library for those, we instead grew the scope of this one to contain all of our commonly used types and narrowing functions.

References

Another Salesforce TypeScript library, @salesforce/kit, builds on this library to add additional utilities. It includes additional JSON support, a lightweight replacement for lodash, and growing support for patterns used in other Salesforce CLI libraries and applications.

Index

Type aliases

AnyConstructor

AnyConstructor: object

A constructor for any type T. T defaults to object when not explicitly supplied.

Type declaration

AnyFunction

AnyFunction: function

Any function returning type T. T defaults to unknown when not explicitly supplied.

Type declaration

    • (...args: unknown[]): T
    • Parameters

      • Rest ...args: unknown[]

      Returns T

AnyJson

Any valid JSON value.

JsonCollection

JsonCollection: JsonMap | JsonArray

Any valid JSON collection value.

JsonPrimitive

JsonPrimitive: Nullable<boolean | number | string>

Any valid JSON primitive value.

KeyOf

KeyOf: Extract<keyof T, string>

An alias for the commonly needed Extract<keyof T, string>.

KeyValue

KeyValue: [string, T]

An alias for a tuple of type [string, T]' for a given generic typeT.Tdefaults tounknown` if not otherwise defined.

Literals

Literals: Extract<{ [K in keyof T]: string extends K ? never : number extends K ? never : K; } extends { [_ in keyof T]: infer U; } ? U : never, string>

Extracts literally defined property names from a type T as a union of key name strings, minus any index signatures.

LiteralsRecord

LiteralsRecord: Record<Literals<T>, U>

Creates a new Record type from the literal properties of a type T, assigning their values the to the type U.

This can be useful for creating interfaces from the keys of an enum so that the keys are available at runtime for meta-programming purposes, while both tying the properties of the generated type to the enum keys and remaining as DRY as possible.

enum QUERY_KEY { id, name, created, updated }
// typeof QUERY_KEY -> {
//     [x: number]: number;
//     readonly id: number;
//     readonly name: number;
//     readonly created: number;
//     readonly updated: number;
// }
interface QueryRecord extends LiteralsRecord<typeof QUERY_KEY, string> { }
// typeof QueryRecord -> {
//     readonly id: string;
//     readonly name: string;
//     readonly created: string;
//     readonly updated: string;
// }
// And for an interface with writable properties, use the following:
interface QueryRecord extends Writable<LiteralsRecord<typeof QUERY_KEY, string>> { }
// typeof QueryRecord -> {
//     id: string;
//     name: string;
//     created: string;
//     updated: string;
// }

Many

Many: T | T[]

A union type for either the parameterized type T or an array of T.

NonOptional

NonOptional: NonOptional<T>

Subtracts undefined from any union type T. This is the opposite of Optional.

Nullable

Nullable: Optional<T | null>

A union type for either the parameterized type T, null, or undefined -- the opposite of the NonNullable builtin conditional type.

Omit

Omit: Pick<T, Exclude<keyof T, K>>

Creates a new type that omits keys in union type K of a target type T.

Optional

Optional: T | undefined

A union type for either the parameterized type T or undefined -- the opposite of NonOptional.

PropertyKey

PropertyKey: string | number | symbol

A union type of string | number | symbol, representing all possible types for object property keys.

RequiredNonNullable

RequiredNonNullable: RequiredNonNullable<T>

Converts a type T that may have optional, nullable properties into a new type with only required properties, while also subtracting null from all possible property values.

type Foo = { bar?: string | undefined | null };
type RequiredNonNullableFoo = RequiredNonNullable<Foo>;
// RequiredNonNullableFoo -> { bar: string };

RequiredNonOptional

RequiredNonOptional: RequiredNonOptional<T>

Converts a type T that may have optional properties into a type T with only required properties (e.g. undefined values are not allowed). Explicit nulls in value unions will still be possible. This is similar to the Required builtin mapped type, but also subtracts undefined from value union types as well as the optional property declaration.

type Foo = { bar?: string | undefined | null };
type RequiredNonOptionalFoo = RequiredNonOptional<Foo>;
// RequiredNonOptionalFoo -> { bar: string | null };

Writable

Writable: object

Converts readonly properties of a type T to writable properties. This is the opposite of the Readonly<T> builtin mapped type.

Type declaration

Functions

asBoolean

  • Narrows an AnyJson value to a boolean if it is type-compatible, or returns undefined otherwise.

    Parameters

    Returns Optional<boolean>

  • Narrows an unknown value to a boolean if it is type-compatible, or returns the provided default otherwise.

    Parameters

    • value: Optional<AnyJson>

      The value to test.

    • defaultValue: boolean

      The default to return if value was undefined or of the incorrect type.

    Returns boolean

asJsonArray

  • Narrows an AnyJson value to a JsonArray if it is type-compatible, or returns undefined otherwise.

    Parameters

    Returns Optional<JsonArray>

  • Narrows an unknown value to a JsonArray if it is type-compatible, or returns the provided default otherwise.

    Parameters

    • value: Optional<AnyJson>

      The value to test.

    • defaultValue: JsonArray

      The default to return if the value was undefined or of the incorrect type.

    Returns JsonArray

asJsonMap

  • Narrows an AnyJson value to a JsonMap if it is type-compatible, or returns undefined otherwise.

    Parameters

    Returns Optional<JsonMap>

  • Narrows an unknown value to a JsonMap if it is type-compatible, or returns the provided default otherwise.

    Parameters

    • value: Optional<AnyJson>

      The value to test.

    • defaultValue: JsonMap

      The default to return if value was undefined or of the incorrect type.

    Returns JsonMap

asNumber

  • Narrows an AnyJson value to a number if it is type-compatible, or returns undefined otherwise.

    Parameters

    Returns Optional<number>

  • Narrows an unknown value to a number if it is type-compatible, or returns the provided default otherwise.

    Parameters

    • value: Optional<AnyJson>

      The value to test.

    • defaultValue: number

      The default to return if value was undefined or of the incorrect type.

    Returns number

asString

  • Narrows an AnyJson value to a string if it is type-compatible, or returns undefined otherwise.

    Parameters

    Returns Optional<string>

  • Narrows an unknown value to a string if it is type-compatible, or returns the provided default otherwise.

    Parameters

    • value: Optional<AnyJson>

      The value to test.

    • defaultValue: string

      The default to return if value was undefined or of the incorrect type.

    Returns string

coerceAnyJson

  • Narrows an unknown value to an AnyJson if it is type-compatible*, or returns undefined otherwise.

    * This is not a 100% safe operation -- it will not deeply validate plain object or array structures to ensure that they contain only AnyJson values. When type-narrowing potential objects or arrays with this function, it's the responsibility of the caller to understand the risks of making such a shallow type assertion over the value data.

    Parameters

    • value: unknown

      The value to test.

    Returns Optional<AnyJson>

  • Narrows an unknown value to an AnyJson if it is type-compatible, or returns the provided default otherwise.

    Parameters

    • value: unknown

      The value to test.

    • defaultValue: AnyJson

      The default to return if value was undefined or of the incorrect type.

    Returns AnyJson

coerceJsonArray

  • Narrows an array of type T to a JsonArray using a shallow type-compatibility check. Use this when the source of the array is known to be JSON-compatible and you want simple type coercion to a JsonArray. Use toJsonArray instead when the value array cannot be guaranteed to be JSON-compatible and you want an assurance of runtime type safety. This is a shortcut for writing asJsonArray(coerceAnyJson(value)).

    Type parameters

    • T

    Parameters

    • value: Optional<T[]>

      The array to coerce.

    Returns Optional<JsonArray>

  • Narrows an array of type T to a JsonArray using a shallow type-compatibility check. Use this when the source of the array is known to be JSON-compatible and you want simple type coercion to a JsonArray. Use toJsonArray instead when the value array cannot be guaranteed to be JSON-compatible and you want an assurance of runtime type safety.

    Type parameters

    • T

    Parameters

    • value: Optional<T[]>

      The array to coerce.

    • defaultValue: JsonArray

      The default to return if value was undefined.

    Returns JsonArray

coerceJsonMap

  • Narrows an object of type T to a JsonMap using a shallow type-compatibility check. Use this when the source of the object is known to be JSON-compatible and you want simple type coercion to a JsonMap. Use toJsonMap instead when the value object cannot be guaranteed to be JSON-compatible and you want an assurance of runtime type safety. This is a shortcut for writing asJsonMap(coerceAnyJson(value)).

    Type parameters

    • T: any

    Parameters

    • value: Optional<T>

      The object to coerce.

    Returns Optional<JsonMap>

  • Narrows an object of type T to a JsonMap using a shallow type-compatibility check. Use this when the source of the object is known to be JSON-compatible and you want simple type coercion to a JsonMap. Use toJsonMap instead when the value object cannot be guaranteed to be JSON-compatible and you want an assurance of runtime type safety.

    Type parameters

    • T: any

    Parameters

    • value: Optional<T>

      The object to coerce.

    • defaultValue: JsonMap

      The default to return if value was undefined.

    Returns JsonMap

definiteEntriesOf

  • definiteEntriesOf<T, K, V>(obj: T): Array<[K, V]>
  • Returns an array of all entry tuples of type [K, NonNullable<T[K]>] in an object T whose values are neither null nor undefined. This can be convenient for enumerating the entries of unknown object with optional properties (including Dictionarys) without worrying about performing checks against possibly undefined or null values.

    See also caveats outlined in entriesOf.

    Type parameters

    • T: any

    • K: KeyOf<T>

    • V: NonNullable<T[K]>

    Parameters

    • obj: T

      The object of interest.

    Returns Array<[K, V]>

definiteKeysOf

  • definiteKeysOf<T>(obj: T): Array<KeyOf<T>>
  • Returns an array of all string keys in an object of type T whose values are neither null nor undefined. This can be convenient for enumerating the keys of definitely assigned properties in an object or Dictionary.

    See also caveats outlined in keysOf.

    Type parameters

    • T: any

    Parameters

    • obj: T

      The object of interest.

    Returns Array<KeyOf<T>>

definiteValuesOf

  • definiteValuesOf<T>(obj: T): Array<NonNullable<T[Extract<keyof T, string>]>>
  • Returns an array of all values of type T in a Dictionary<T> for values that are neither null nor undefined. This can be convenient for enumerating all non-nullable values of unknown Dictionary.

    Type parameters

    • T: any

    Parameters

    • obj: T

      The object of interest.

    Returns Array<NonNullable<T[Extract<keyof T, string>]>>

ensure

  • ensure<T>(value: Nullable<T>, message?: undefined | string): T
  • Narrows a type Nullable<T> to a T or raises an error.

    throws

    UnexpectedValueTypeError If the value was undefined.

    Type parameters

    • T

    Parameters

    • value: Nullable<T>

      The value to test.

    • Optional message: undefined | string

      The error message to use if value is undefined or null.

    Returns T

ensureAnyJson

  • ensureAnyJson(value: unknown, message?: undefined | string): AnyJson
  • Narrows an unknown value to an AnyJson if it is type-compatible, or returns undefined otherwise.

    See also caveats noted in isAnyJson.

    throws

    UnexpectedValueTypeError If the value was not a JSON value type.

    Parameters

    • value: unknown

      An AnyJson value to test.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns AnyJson

ensureBoolean

  • ensureBoolean(value: Optional<AnyJson>, message?: undefined | string): boolean
  • Narrows an AnyJson value to a boolean if it is type-compatible, or raises an error otherwise.

    throws

    UnexpectedValueTypeError If the value was undefined.

    Parameters

    • value: Optional<AnyJson>

      An AnyJson value to test.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns boolean

ensureJsonArray

  • Narrows an AnyJson value to a JsonArray if it is type-compatible, or raises an error otherwise.

    throws

    UnexpectedValueTypeError If the value was undefined.

    Parameters

    • value: Optional<AnyJson>

      An AnyJson value to test.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns JsonArray

ensureJsonMap

  • Narrows an AnyJson value to a JsonMap if it is type-compatible, or raises an error otherwise.

    throws

    UnexpectedValueTypeError If the value was undefined.

    Parameters

    • value: Optional<AnyJson>

      An AnyJson value to test.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns JsonMap

ensureNumber

  • ensureNumber(value: Optional<AnyJson>, message?: undefined | string): number
  • Narrows an AnyJson value to a number if it is type-compatible, or raises an error otherwise.

    throws

    UnexpectedValueTypeError If the value was undefined.

    Parameters

    • value: Optional<AnyJson>

      An AnyJson value to test.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns number

ensureString

  • ensureString(value: Optional<AnyJson>, message?: undefined | string): string
  • Narrows an AnyJson value to a string if it is type-compatible, or raises an error otherwise.

    throws

    UnexpectedValueTypeError If the value was undefined.

    Parameters

    • value: Optional<AnyJson>

      An AnyJson value to test.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns string

entriesOf

  • entriesOf<T, K>(obj: T): Array<[K, T[K]]>
  • Returns the entries of an object of type T. This is like Object.entries except the return type captures the known keys and value types of T.

    Note that it is the responsibility of the caller to use this wisely -- there are cases where the runtime set of entries returned may be broader than the type checked set at compile time, so there's potential for this to be abused in ways that are not inherently type safe. For example, given base class Animal, subclass Fish, and const animal: Animal = new Fish(); then entriesOf(animal) will not type-check the entire set of keys of the object animal since it is actually an instance of type Fish, which has an extended property set.

    In general, it should be both convenient and type-safe to use this when enumerating the entries of simple data objects with known properties.

    interface Point { x: number; y: number; }
    const point: Point = { x: 1, y: 2 };
    // type of entries -> ['x' | 'y', number][]
    const entries = entriesOf(point);
    for (const entry of entries) {
      console.log(entry[0], entry[1]);
    }
    // x 1
    // y 2

    Type parameters

    Parameters

    • obj: T

      The object of interest.

    Returns Array<[K, T[K]]>

getAsAnyJson

  • Gets AnyJson element of a JsonMap given a query path.

    Parameters

    Returns Optional<AnyJson>

  • Gets an AnyJson element of a JsonMap given a query path, returning a default if not found or not type-compatible.

    Parameters

    Returns AnyJson

getAsBoolean

  • Gets a boolean element of a JsonMap given a query path.

    Parameters

    Returns Optional<boolean>

  • Gets a boolean element of a JsonMap given a query path, returning a default if not found or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • defaultValue: boolean

      A fallback value.

    Returns boolean

getAsJsonArray

  • Gets a JsonArray element of a JsonMap given a query path.

    Parameters

    Returns Optional<JsonArray>

  • Gets a JsonArray element of a JsonMap given a query path, returning a default if not found or not type-compatible.

    Parameters

    Returns JsonArray

getAsJsonMap

  • Gets a JsonMap element of a JsonMap given a query path.

    Parameters

    Returns Optional<JsonMap>

  • Gets a JsonMap element of a JsonMap given a query path, returning a default if not found or not type-compatible.

    Parameters

    Returns JsonMap

getAsNumber

  • Gets a number element of a JsonMap given a query path.

    Parameters

    Returns Optional<number>

  • Gets a number element of a JsonMap given a query path, returning a default if not found or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • defaultValue: number

      A fallback value.

    Returns number

getAsString

  • Gets a string element of a JsonMap given a query path.

    Parameters

    Returns Optional<string>

  • Gets a string element of a JsonMap given a query path, returning a default if not found or not type-compatible.

    Parameters

    • json: JsonMap

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • defaultValue: string

      A fallback value.

    Returns string

getEnsureAnyJson

  • Gets an AnyJson element of a JsonMap given a query path, or raises an error if not found or not type-compatible.

    throws

    UnexpectedValueTypeError If the value was undefined or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns AnyJson

getEnsureBoolean

  • getEnsureBoolean(json: Optional<JsonMap>, path: Many<string>, message?: undefined | string): boolean
  • Gets a boolean element of a JsonMap given a query path, or raises an error if not found or not type-compatible.

    throws

    UnexpectedValueTypeError If the value was undefined or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns boolean

getEnsureJsonArray

  • Gets a JsonArray element of a JsonMap given a query path, or raises an error if not found or not type-compatible.

    throws

    UnexpectedValueTypeError If the value was undefined or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns JsonArray

getEnsureJsonMap

  • Gets a JsonMap element of a JsonMap given a query path, or raises an error if not found or not type-compatible.

    throws

    UnexpectedValueTypeError If the value was undefined or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns JsonMap

getEnsureNumber

  • getEnsureNumber(json: Optional<JsonMap>, path: Many<string>, message?: undefined | string): number
  • Gets a number element of a JsonMap given a query path, or raises an error if not found or not type-compatible.

    throws

    UnexpectedValueTypeError If the value was undefined or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns number

getEnsureString

  • getEnsureString(json: Optional<JsonMap>, path: Many<string>, message?: undefined | string): string
  • Gets a string element of a JsonMap given a query path, or raises an error if not found or not type-compatible.

    throws

    UnexpectedValueTypeError If the value was undefined or not type-compatible.

    Parameters

    • json: Optional<JsonMap>

      The JsonMap to query.

    • path: Many<string>

      The query path.

    • Optional message: undefined | string

      The error message to use if value is not type-compatible.

    Returns string

isAnyJson

  • isAnyJson(value: Optional<unknown>): boolean
  • Tests whether unknown value is a valid JSON type. Note that objects and arrays are only checked using a shallow test. To be sure that a given value is JSON-compatible at runtime, see toAnyJson.

    Parameters

    • value: Optional<unknown>

      The value to test.

    Returns boolean

isArray

  • isArray<T>(value: unknown): boolean
  • Tests whether an unknown value is an Array.

    Type parameters

    • T

    Parameters

    • value: unknown

      Any value to test.

    Returns boolean

isBoolean

  • isBoolean(value: unknown): boolean
  • Tests whether an unknown value is a boolean.

    Parameters

    • value: unknown

      Any value to test.

    Returns boolean

isFunction

  • isFunction(value: unknown): boolean
  • Tests whether an unknown value is a function.

    Parameters

    • value: unknown

      Any value to test.

    Returns boolean

isJsonArray

  • Tests whether an AnyJson value is an array.

    Parameters

    Returns boolean

isJsonMap

  • Tests whether an AnyJson value is an object.

    Parameters

    Returns boolean

isKeyOf

  • isKeyOf<T, K>(key: string, obj: T): boolean
  • Tests whether or not a key string is a key of the given object type T.

    Type parameters

    Parameters

    • key: string

      The string to test as a key of the target object.

    • obj: T

      The target object to check the key in.

    Returns boolean

isNumber

  • isNumber(value: unknown): boolean
  • Tests whether an unknown value is a number.

    Parameters

    • value: unknown

      Any value to test.

    Returns boolean

isObject

  • isObject(value: unknown): boolean
  • Tests whether an unknown value is an object subtype.

    Parameters

    • value: unknown

      Any value to test.

    Returns boolean

isPlainObject

  • isPlainObject(value: unknown): boolean
  • Tests whether or not an unknown value is a plain JS object.

    Parameters

    • value: unknown

      Any value to test.

    Returns boolean

isString

  • isString(value: unknown): boolean
  • Tests whether an unknown value is a string.

    Parameters

    • value: unknown

      Any value to test.

    Returns boolean

keysOf

  • keysOf<T, K>(obj: T): K[]
  • Returns the keys of an object of type T. This is like Object.keys except the return type captures the known keys of T.

    Note that it is the responsibility of the caller to use this wisely -- there are cases where the runtime set of keys returned may be broader than the type checked set at compile time, so there's potential for this to be abused in ways that are not inherently type safe. For example, given base class Animal, subclass Fish, and const animal: Animal = new Fish(); then keysOf(animal) will not type-check the entire set of keys of the object animal since it is actually an instance of type Fish, which has an extended property set.

    In general, it should be both convenient and type-safe to use this when enumerating the keys of simple data objects with known properties.

    interface Point { x: number; y: number; }
    const point: Point = { x: 1, y: 2 };
    const keys = keysOf(point);
    // type of keys -> ('a' | 'b')[]
    for (const key of keys) {
      console.log(key, point[key]);
    }
    // x 1
    // y 2

    Type parameters

    Parameters

    • obj: T

      The object of interest.

    Returns K[]

toAnyJson

  • Narrows an object of type T to an AnyJson following a deep, brute-force conversion of the object's data to only consist of JSON-compatible values by performing a basic JSON clone on the object. This is preferable to using the weaker coerceAnyJson(unknown) to type-narrow an arbitrary value to an AnyJson when the value's source is unknown, but it comes with the increased overhead of performing the deep JSON clone to ensure runtime type safety. The use of JSON cloning guarantees type safety by omitting non-JSON-compatible elements from the resulting JSON data structure. Use coerceAnyJson(unknown) when the value object can be guaranteed to be JSON-compatible and only needs type narrowing.

    throws

    JsonCloneError If the value values contain circular references.

    Type parameters

    • T

    Parameters

    • value: Optional<T>

      The value to convert.

    Returns Optional<AnyJson>

  • Narrows an object of type T to an AnyJson following a deep, brute-force conversion of the object's data to only consist of JSON-compatible values by performing a basic JSON clone on the object. This is preferable to using the weaker coerceAnyJson(unknown) to type-narrow an arbitrary value to an AnyJson when the value's source is unknown, but it comes with the increased overhead of performing the deep JSON clone to ensure runtime type safety. The use of JSON cloning guarantees type safety by omitting non-JSON-compatible elements from the resulting JSON data structure. Use coerceAnyJson(unknown) when the value object can be guaranteed to be JSON-compatible and only needs type narrowing.

    throws

    JsonCloneError If the value values contain circular references.

    Type parameters

    • T

    Parameters

    • value: Optional<T>

      The value to convert.

    • defaultValue: AnyJson

      The default to return if value was undefined.

    Returns AnyJson

toJsonArray

  • Narrows an array of type T to a JsonArray following a deep, brute-force conversion of the array's data to only consist of JSON-compatible values by performing a basic JSON clone on the array. This is preferable to using the weaker coerceJsonArray(array) to type-narrow an arbitrary array to a JsonArray when the array's source is unknown, but it comes with the increased overhead of performing the deep JSON clone to ensure runtime type safety. The use of JSON cloning guarantees type safety by omitting non-JSON-compatible elements from the resulting JSON data structure. Non-JSON entries will be converted to nulls. Use coerceJsonArray(array) when the value object can be guaranteed to be JSON-compatible and only needs type narrowing.

    throws

    JsonCloneError If the array values contain circular references.

    Type parameters

    • T

    Parameters

    • value: Optional<T[]>

      The array to convert.

    Returns Optional<JsonArray>

  • Narrows an object of type T to a JsonMap following a deep, brute-force conversion of the object's data to only consist of JSON-compatible values by performing a basic JSON clone on the object. This is preferable to using the weaker coerceJsonMap(object) to type-narrow an arbitrary array to a JsonMap when the object's source is unknown, but it comes with the increased overhead of performing the deep JSON clone to ensure runtime type safety. The use of JSON cloning guarantees type safety by omitting non-JSON-compatible elements from the resulting JSON data structure. Non-JSON entries will be converted to nulls. Use coerceJsonArray(array) when the value object can be guaranteed to be JSON-compatible and only needs type narrowing.

    throws

    JsonCloneError If the array values contain circular references.

    Type parameters

    • T

    Parameters

    • value: Optional<T[]>

      The array to convert.

    • defaultValue: JsonArray

      The default to return if the value was undefined or of the incorrect type.

    Returns JsonArray

toJsonMap

  • Narrows an object of type T to a JsonMap following a deep, brute-force conversion of the object's data to only consist of JSON-compatible values by performing a basic JSON clone on the object. This is preferable to using the weaker coerceJsonMap(object) to type-narrow an arbitrary object to a JsonMap when the object's source is unknown, but it comes with the increased overhead of performing the deep JSON clone to ensure runtime type safety. The use of JSON cloning guarantees type safety by omitting non-JSON-compatible elements from the resulting JSON data structure. Use coerceJsonMap(object) when the value object can be guaranteed to be JSON-compatible and only needs type narrowing.

    throws

    JsonCloneError If the object values contain circular references.

    Type parameters

    • T: any

    Parameters

    • value: Optional<T>

      The object to convert.

    Returns Optional<JsonMap>

  • Narrows an object of type T to a JsonMap following a deep, brute-force conversion of the object's data to only consist of JSON-compatible values by performing a basic JSON clone on the object. This is preferable to using the weaker coerceJsonMap(object) to type-narrow an arbitrary object to a JsonMap when the object's source is unknown, but it comes with the increased overhead of performing the deep JSON clone to ensure runtime type safety. The use of JSON cloning guarantees type safety by omitting non-JSON-compatible elements from the resulting JSON data structure. Use coerceJsonMap(object) when the value object can be guaranteed to be JSON-compatible and only needs type narrowing.

    throws

    JsonCloneError If the object values contain circular references.

    Type parameters

    • T: any

    Parameters

    • value: Optional<T>

      The object to convert.

    • defaultValue: JsonMap

      The default to return if value was undefined.

    Returns JsonMap

valuesOf

  • valuesOf<T, K>(obj: T): Array<T[K]>
  • Returns the values of an object of type T. This is like Object.values except the return type captures the possible value types of T.

    Note that it is the responsibility of the caller to use this wisely -- there are cases where the runtime set of values returned may be broader than the type checked set at compile time, so there's potential for this to be abused in ways that are not inherently type safe. For example, given base class Animal, subclass Fish, and const animal: Animal = new Fish(); then valuesOf(animal) will not type-check the entire set of values of the object animal since it is actually an instance of type Fish, which has an extended property set.

    In general, it should be both convenient and type-safe to use this when enumerating the values of simple data objects with known properties.

    interface Point { x: number; y: number; }
    const point: Point = { x: 1, y: 2 };
    const values = valuesOf(point);
    // type of values -> number[]
    for (const value of values) {
      console.log(value);
    }
    // 1
    // 2

    Type parameters

    Parameters

    • obj: T

      The object of interest.

    Returns Array<T[K]>