I have been working on creating a function with the following structure:
function validate<T>(input: T, message?: string): T & asserts input {
if (!input) {
throw new Error(message)
}
return input
}
The main aim of this function is to return the unaltered input
while also indicating to the compiler that the returned value is truthy. This enables it to be used as a standalone statement or within an expression seamlessly.
const result: boolean = true;
// ... code segment that might change the value of 'result' to false
validate(result);
const element: HTMLElement = validate(document.getElementById('foo'));
Regrettably, the syntax presented above does not function as expected (playground). Is there a way to achieve this functionality in TypeScript?
I have searched extensively for official documentation on assertion functions outside of the TypeScript 3.7 Release notes, which only showcase assertion functions that implicitly return void
.
The closest solution I could devise is a workaround applicable solely to object types, as they can never be falsy:
function validate<T extends object>(input: T | null | undefined, message?: string): T {
if (!input) {
throw new Error(message)
}
return input
}