Objects.structure()
Syntax
function structure<T extends Structure>(object: object, struct: T): object is MappedStructure<T>
Type guard that checks if an object conforms to the given shape.
| Parameters | |
object
|
The object to perform the structural check on. |
struct
|
A valid |
exhaustive
Optional
|
If true, the check is exhaustive, that is, all properties
of This is |
Example 1
import { Objects, Structure } from 'potence';
import { oneOf, string, number, nullish, instanceOf } from 'potence/fluent/matchers';
import { fetchJson } from 'api.ts';
// Assume you have a function that fetches some JSON from a web API.
// Since the JSON comes from an endpoint you have no control over, you can't
// be sure of its type.
// Note: normally this would be an asynchronous function, however for the sake
// of simplicity let's assume the fetch is a blocking call.
const obj: object = fetchJson();
// Define the shape of the expected JSON.
// It is recommended you define your Structures in another file and import them
// (rather than defining them inline).
const shape: Structure = {
results: [{
mandatoryProp: string(),
optionalProp: oneOf(number(), nullish())
}],
offset: number()
};
// Check whether obj conforms to shape.
if (Objects.structure(obj, shape)) {
let sum: number = 0;
obj.results.forEach(result => { // no error, obj.results is of type array
if (result.mandatoryProp === 'myProp') { // no error, result.mandatoryProp is of type string
sum += result.optionalProp; // error, optionalProp may be undefined
}
});
}
Example 2
import { Objects } from 'potence';
class Owner { ... }
interface Animal {
name: string;
owner?: Owner;
pastOwners: Owner[];
}
function isAnimal(obj: unknown): obj is Animal {
return isObject(obj) && Objects.structure(obj, {
name: number(),
owner: oneOf(instanceOf(Owner), nullish()),
pastOwners: arrayOf(instanceOf(Owner))
});
}
Remarks
Due to the fact that this function is a
type guard,
this makes it an extremely powerful tool for quickly checking whether an unknown
object contains a known set of properties of a known type. As long as you use
this function properly, you should never have to manually cast a value to
another type as TypeScript will understand that the source object corresponds to
the passed object structure if the return type is true.
The function can also be especially useful for use in a user-defined type guard,
as seen in Example 2 above, even though you lose the advantages of
Objects.structure()’s own type guard this way.
See Structure for detailed information
on the Structure type as well as a complete example showing all possible
values.