Recently, I was working on a developing a server that responds to JSON RPC calls using TypeScript.

Many of the methods in the RPC server follows this template, or similar variations of it:

    async stop(params: JSONRPCParams | undefined) {         if (!Array.isArray(params) || params.length === 0) {             throw new JSONRPCErrorException('Invalid parameters provided', JSONRPCErrorCode.InvalidParams);         }         ... other code here ...     };

The if block checks that params is an array and that the length is greater than 0, otherwise, it throws an error.

When you have many RPC methods, it can get challenging to check params.

If you move the if check into a function, like so:

checkParams(params: JSONRPCParams | undefined) {         if (!Array.isArray(params) || params.length < 1) {             throw new JSONRPCErrorException("Invalid parameter", JSONRPCErrorCode.InvalidParams);         }
    }
    async start(params: JSONRPCParams | undefined) {
        this.checkParams(params);       
  const paramsA = params[0]; // you'll get a 'params' is possibly 'undefined'.ts(18048)  
}

You'll get an error about params being possibly undefined. But if you redeclare checkParams as an Assertion Function (the renaming of the function is to fit its purpose):

    validateParams(params: JSONRPCParams | undefined): asserts params is any[] {         if (!Array.isArray(params) || params.length < 1) {             throw new JSONRPCErrorException("Invalid parameter", JSONRPCErrorCode.InvalidParams);
        }
    }
    async start(params: JSONRPCParams | undefined) {         this.validateParams(params);         const params0 = params[0];     }

then when validateParams returns, it'll be an array of any (any[]). In fact, whatever is asserted by validateParams will be considered to be true. Also, one can transform the input, narrow it and return "asserts params is number[]" and the entire scope of the function body after the call to this.validateParams will treat params as an number[].
Also, note that an Assertion Function doesn't necessarily need to have a body, it can be empty! However, I can't imagine how you'll assert something without a body at this point in time.

So, that's why an Assertion Function is useful and comes in handy!