Most precise type after checking `typeof a === 'object' && a !== null`

132 Views Asked by At

I have this assertion function, which checks that the passed value is an object (according to the typeof operator), but excluding null:

export function assertIsJavaScriptObjectExceptNull(value: unknown) {
    if (typeof value !== 'object' || value === null) {
        throw Error('Value is not an object.');
    }
}

I'd like to add an assertion signature to this function, so that it helps with type narrowing when used. What is the "most correct" type to use here?

export function assertIsJavaScriptObjectExceptNull(value: unknown): asserts value is <type> {
    if (typeof value !== 'object' || value === null) {
        throw Error('Value is not an object.');
    }
}

Is it {[key: string | number | symbol]: unknown}, or Record<keyof unknown, unknown>, or Object, or something else?

I'm looking for the type that matches TypeScript's understanding of what this type should be. I know that TypeScript has many settings which can slightly influence this and that JavaScript engines have quirks and bugs that might lead to a result that contradict this understanding. So there might not be a single best answer.

1

There are 1 best solutions below

0
wonderflame On BEST ANSWER

What are you looking for is the object type, which represents any non-primitive type. Please, avoid using Object which is a JavaScript class and is recommended to be avoided in the official Do's and Don'ts.

object allows us to make sure that the value assigned to a type is not primitive:

const noError: {toString(): string} = 1
const withError: object & {toString(): string} = 1;

Basically, you can intersect anything with object to make sure that the type doesn't allow primitive values.

For a better understanding of the sets theory in the typescript, refer to this blog post