@nestia/fetcher
Version:
Fetcher library of Nestia SDK
100 lines (95 loc) • 3.21 kB
text/typescript
/**
* Propagation type.
*
* `IPropagation` is a type gathering all possible status codes and their body
* data types as a discriminated union type. You can specify the status code and
* its body data type just by using conditional statement like below.
*
* ```typescript
* type Output = IPropagation<{
* 200: ISeller.IAuthorized;
* 400: TypeGuardError.IProps;
* >};
*
* const output: Output = await sdk.sellers.authenticate.join(input);
* if (output.success) {
* // automatically casted to "ISeller.IAuthorized" type
* const authorized: ISeller.IAuthorized = output.data;
* } else if (output.status === 400) {
* // automatically casted to "TypeGuardError.IProps" type
* const error: TypeGuardError.IProps = output.data;
* } else {
* // unknown type when out of pre-defined status codes
* const result: unknown = output.data;
* }
* ```
*
* For reference, this `IPropagation` type is utilized by SDK library generated
* by `@nestia/sdk`, when you've configured {@link INestiaConfig.propagate} to be
* `true`. In that case, SDK functions generated by `@nestia/sdk` no more
* returns response DTO typed data directly, but returns this `IPropagation`
* typed object instead.
*
* @author Jeongho Nam - https://github.com/samchon
* @template StatusMap Map of status code and its body data type.
* @template Success Default success status code.
*/
export type IPropagation<
StatusMap extends {
[P in IPropagation.Status]?: any;
},
Success extends number = 200 | 201,
> =
| {
[P in keyof StatusMap]: IPropagation.IBranch<
P extends Success ? true : false,
P,
StatusMap[P]
>;
}[keyof StatusMap]
| IPropagation.IBranch<false, unknown, unknown>;
export namespace IPropagation {
/**
* Type of configurable status codes.
*
* The special characters like `2XX`, `3XX`, `4XX`, `5XX` are meaning the
* range of status codes. If `5XX` is specified, it means the status code is
* in the range of `500` to `599`.
*/
export type Status = number | "2XX" | "3XX" | "4XX" | "5XX";
/**
* Branch type of propagation.
*
* `IPropagation.IBranch` is a branch type composing `IPropagation` type,
* which is gathering all possible status codes and their body data types as a
* union type.
*/
export interface IBranch<Success extends boolean, StatusValue, BodyData> {
success: Success;
status: StatusValue extends "2XX" | "3XX" | "4XX" | "5XX"
? StatusRange<StatusValue>
: StatusValue extends number
? StatusValue
: never;
data: BodyData;
headers: Record<string, string | string[]>;
}
/** Range of status codes by the first digit. */
export type StatusRange<T extends "2XX" | "3XX" | "4XX" | "5XX"> = T extends 0
? IntRange<200, 299>
: T extends 3
? IntRange<300, 399>
: T extends 4
? IntRange<400, 499>
: IntRange<500, 599>;
type IntRange<F extends number, T extends number> = Exclude<
Enumerate<T>,
Enumerate<F>
>;
type Enumerate<
N extends number,
Acc extends number[] = [],
> = Acc["length"] extends N
? Acc[number]
: Enumerate<N, [...Acc, Acc["length"]]>;
}