@strapi/types
Version:
Shared typescript types for Strapi internal use
90 lines • 3.71 kB
TypeScript
import type { Array, If, StrictEqual } from '.';
/**
* Conditionally assigns a fallback type {@link TFallback} to a type {@link TValue}, if {@link TValue} resolves to `never`.
*
* Otherwise, it assigns the type of {@link TValue}.
*
* @template TValue - The original type which could be any type or `never`.
* @template TFallback - The fallback type that will be assigned to {@link TValue} if {@link TValue} is `never`. It defaults to `unknown`.
*
* @remark
* This type becomes useful when working with conditional types where there are possibilities of ending up with `never` type.
*
* It provides a way to ensure that, in such situations, the type defaults to a more meaningful type rather than `never`.
*
* @example
* ```typescript
* type User = { name: 'John' }
*
* type X = Guard.Never<User>; // X: User
* ```
*
* @example
* ```typescript
* type NoType = never;
*
* type X = Guard.Never<NoType>; // X: unknown
* type Y = Guard.Never<NoType, string>; // Y: string
* ```
*/
export type Never<TValue, TFallback = unknown> = OfTypes<[never], TValue, TFallback>;
/**
* Conditionally assigns a fallback type {@link TFallback} to a type {@link TValue}, if {@link TValue} resolves to `{}`.
*
* Otherwise, it assigns the type of {@link TValue}.
*
* @template TValue - The original type which could be any type or `{}`.
* @template TFallback - The fallback type that will be assigned to {@link TValue} if {@link TValue} is `{}`. It defaults to `unknown`.
*
* @remark
* This type becomes useful when working with conditional types where there are possibilities of ending up with `{}` type.
*
* It provides a way to ensure that, in such situations, the type defaults to a more meaningful type rather than `{}`.
*
* @example
* ```typescript
* type User = { name: 'John' }
*
* type X = Guard.EmptyObject<User>; // X: User
* ```
*
* @example
* ```typescript
* type MyObj = {};
*
* type X = Guard.EmptyObject<MyObj>; // X: unknown
* type Y = Guard.EmptyObject<MyObj, string>; // Y: string
* ```
*/
export type EmptyObject<TValue, TFallback = unknown> = OfTypes<[{}], TValue, TFallback>;
/**
* Conditionally assigning a fallback type (@link TFallback) if the value type ({@link TValue}) matches any of the types in {@link TTypes}.
*
* It basically enables conditional type assignments based on type matching.
*
* The value is checked against the list of types iteratively. If it matches any type from the list, the fallback type is assigned.
*
* If it doesn't match, the value's original type is maintained.
*
* If no fallback is provided, unknown type is used by default.
*
* @template TTypes - A tuple of types to match the value against. It must extend Array<unknown>
* @template TValue - The value whose type is checked against TTypes.
* @template TFallback - The type to be assigned if TValue matches any member of TTypes. It defaults to unknown.
*
* @example
* Here, the `TValue` is `string` which exists in the `TTypes` list. Thus, the `TFallback` which is `null` is returned.
* ```typescript
* type Result = OfTypes<[string, number], string, null>; // Result: null
* ```
*
* Here, the `TValue` is `boolean` which does not exist in the `TTypes` list. Thus, the `TValue` is returned as no match was found.
* ```typescript
* type Result = OfTypes<[string, number], boolean, number>; // Result: boolean
* ```
*/
export type OfTypes<TTypes extends unknown[], TValue, TFallback = unknown> = TTypes extends [
infer THead extends unknown,
...infer TTail extends unknown[]
] ? If<StrictEqual<TValue, THead>, TFallback, If<Array.IsNotEmpty<TTail>, OfTypes<TTail, TValue, TFallback>, TValue>> : never;
//# sourceMappingURL=guard.d.ts.map