type Result<T> = 
  T | 
  Error;

const someFunc = (isError: boolean): Result<string> => {
    if (isError) {
        return new Error();
    }
    return 'Success!';
};

const otherFunc = (isError: boolean): Result<number> => {
    if (isError) {
        return new Error();
    }
    return 10;
};

// not an error, return the success result
console.log(someFunc(false));
console.log(otherFunc(false));

// error, return the error
console.log(otherFunc(true));
console.log(someFunc(true));

This approach is in line with Haskell's use of an Either type for error handling.

See also: