Ts Result
Result pattern.
Example Usage
import type {
Result,
ResultAlwaysSuccess,
InferResultSuccess,
InferResultError
} from './ts-result';
// ========================
// Result
// ========================
type Fn1Result = Result<{ name: string; }, 'FETCH_FAILED'>;
const fn1 = async (): Promise<Fn1Result> => {
// ts force you to return a discriminated union
try {
const result = await fetch('https://api.example.com');
// for error not unexpected
if (!result.ok) {
return {
status: 'error',
code: 'FETCH_FAILED',
message: 'Fetch status is not ok: ' + result.status,
};
}
// for success
return {
status: 'success',
data: await result.json(),
};
}
catch (error) {
// for error unexpected
return {
status: 'error',
code: 'UNKNOWN_ERROR',
message: 'Something went wrong with fetch',
};
}
};
// ========================
// ResultAlwaysSuccess
// ========================
type Fn2Result = ResultAlwaysSuccess<{ name: string; }>;
const fn2 = async (): Promise<Fn2Result> => {
// ts force you to return a value with status === 'success'
// use this if you know that error is not possible, or if you want to treat error as success
// ... do your work
return {
status: 'success',
data: { name: 'John Doe' },
};
};
// ========================
// Infer Types
// ========================
type Fn1ResultSuccess = InferResultSuccess<Fn1Result>;
type Fn1ResultError = InferResultError<Fn1Result>;
type Fn3Result = Result<
Fn1ResultSuccess['data'],
"INVALID_INPUT" | Fn1ResultError['code']
>;
const fn3 = async (text: string): Promise<Fn3Result> => {
try {
// if invalid input -> return `INVALID_INPUT` error code
if (text.length < 3) {
return {
status: 'error',
code: 'INVALID_INPUT',
message: 'Invalid input',
};
}
// if error in sub fn -> return sub fn error
const fn1Result = await fn1();
if (fn1Result.status === 'error') {
return fn1Result;
}
// if success in sub fn -> return sub fn success
return {
status: 'success',
data: fn1Result.data,
};
}
catch (error) {
// if error unexpected -> return `UNKNOWN_ERROR` error code
return {
status: 'error',
code: 'UNKNOWN_ERROR',
message: 'Something went wrong',
};
}
};
Dependencies
No dependencies
Auto Install
npx shadcn@latest add https://shadcn-registry-ts.vercel.app/r/util-ts-result.json
Manual Install
ts-result.ts
/**
* Source: http://localhost:3000
*/
/** Create a Result Success type */
type ResultSuccess<S> = {
status: 'success';
data: S;
};
/** Create a Result Error type */
type ResultError<Code extends string> = {
status: 'error';
code: Code | 'UNKNOWN_ERROR',
message: string;
};
/**
* Create a Result type.
* You must pass two generics:
* - the first will be the `data` prop of `success` path.
* - the second will be the `code` prop of `error` path.
* */
export type Result<S, E extends string> = ResultSuccess<S> | ResultError<E>;
/**
* Create a Result type that cannot have `error` path.
* You must pass one generic:
* - will be the `data` prop of `success` path.
* */
export type ResultAlwaysSuccess<S> = ResultSuccess<S>;
/** Utility used to infer the `success` discriminated union of a Result type */
export type InferResultSuccess<R> = Extract<R, { status: 'success'; }>;
/** Utility used to infer the `error` discriminated union of a Result type */
export type InferResultError<R> = Extract<R, { status: 'error'; }>;
Test
No test
Command Palette
Search for a command to run...