
Research
2025 Report: Destructive Malware in Open Source Packages
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.
@typ3/throwable
Advanced tools
A type-safe way to handle Error in TypeScript
By default, we use try, catch, throw to handle error in JS/TS. But it's not type-safe -- we cannot tell what error a function may throw. It makes throw risky -- any unhandled error will make the program crash, which probably is not something we want.
All we need is a way to semantically tell us there might be a error that should be handled.
T | undefined lacks of detail infoT | Error is not convenient to work withHaskell's Either type might be a solution to this scenario. This project rename it to Throwable for better readability.
We can use Throwable<TReturn, TError> to mark a return type of a function to declare it will return TError if error occurred, otherwise TReturn;
function div(a: number, b: number): Throwable<number, 'divZero' | 'divNaN'> {
if (b === 0) {
return Err('divZero');
}
if (Number.isNaN(b)) {
return Err('divNaN');
}
return Ok(a / b);
}
function aDivBDivB(a: number, b: number): Throwable<number, 'divZero'> {
return div(a, b).ifOk(c => div(c, b));
}
Install
yarn add @typ3/throwable
Basic usage
import {Ok, Err, Throwable} from '@typ3/throwable'
// in deno
import {Ok, Err, Throwable} from 'https://deno.land/x/throwable@v0'
function parse(input: string): Throwable<string[], 'invalid'> {
const ans = []
if (!input.startsWith('{')) {
// Rather than `throw new Error()`
return Err('invalid');
}
...
return Ok(ans);
}
Throwable interface
interface Throwable<TReturn, TError> {
/**
* return the concrete error if it is an error
*/
get error(): TError | undefined
/**
* return the value if it is not an error
*/
get value(): TReturn | undefined
get isOk(): boolean;
get isError(): boolean;
/**
* if `this.value` is not error, then return `func(this.value)`
* otherwise return `this.error`
*/
pipe<T>(func: (value: TReturn) => T): Throwable<T, TError>;
/**
* if this.value is valid, return this.value, otherwise return sub
*/
or<T>(sub: T): TReturn | T;
/**
* if this.value is valid return it, otherwise throw the error
*/
unwrap(): TReturn;
}
function Ok<TReturn, TError=any>(v: TReturn): Throwable<TReturn, TError>;
function Err<TError, TReturn=any>(v: TError): Throwable<TReturn, TError>;
Use Casetype MThrowable = Throwable<T, 'notExists' | {type: 'parseError', msg: string} >;
function readJsonFile<T>(path: string): Promise<MThrowable>{
...
}
async function readName(path: string): Promise<MThrowable>{
return (await readJsonFile(path)).pipe(x => x.name);
}
function getValidNames(paths: string[]): Promise<string[]> {
return Promise.all(paths.map(readName)).filter(x => x.isOk());
}
FAQs
🦾 A type-safe way to express error
We found that @typ3/throwable demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.

Research
/Security News
A five-month operation turned 27 npm packages into durable hosting for browser-run lures that mimic document-sharing portals and Microsoft sign-in, targeting 25 organizations across manufacturing, industrial automation, plastics, and healthcare for credential theft.