mirror of
https://github.com/strapi/strapi.git
synced 2025-11-12 00:03:40 +00:00
Move utils to namespaces & fix types
This commit is contained in:
parent
f0841f681d
commit
94e3595718
@ -73,7 +73,7 @@ export const TransferGroupPresets: TransferGroupFilter = {
|
||||
export const DEFAULT_VERSION_STRATEGY = 'ignore';
|
||||
export const DEFAULT_SCHEMA_STRATEGY = 'strict';
|
||||
|
||||
type SchemaMap = Utils.StringRecord<Schema.Schema>;
|
||||
type SchemaMap = Utils.String.Dict<Schema.Schema>;
|
||||
|
||||
class TransferEngine<
|
||||
S extends ISourceProvider = ISourceProvider,
|
||||
|
||||
@ -263,7 +263,7 @@ class RemoteStrapiDestinationProvider implements IDestinationProvider {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
return this.dispatcher.dispatchTransferAction<Utils.StringRecord<Schema.Schema>>('getSchemas');
|
||||
return this.dispatcher.dispatchTransferAction<Utils.String.Dict<Schema.Schema>>('getSchemas');
|
||||
}
|
||||
|
||||
createEntitiesWriteStream(): Writable {
|
||||
|
||||
@ -278,7 +278,7 @@ class RemoteStrapiSourceProvider implements ISourceProvider {
|
||||
|
||||
async getSchemas() {
|
||||
const schemas =
|
||||
(await this.dispatcher?.dispatchTransferAction<Utils.StringRecord<Schema.Schema>>(
|
||||
(await this.dispatcher?.dispatchTransferAction<Utils.String.Dict<Schema.Schema>>(
|
||||
'getSchemas'
|
||||
)) ?? null;
|
||||
|
||||
|
||||
@ -22,6 +22,6 @@ const VALID_SCHEMA_PROPERTIES = [
|
||||
* Sanitize a schemas dictionary by omitting unwanted properties
|
||||
* The list of allowed properties can be found here: {@link VALID_SCHEMA_PROPERTIES}
|
||||
*/
|
||||
export const mapSchemasValues = (schemas: Utils.StringRecord<Schema.Schema>) => {
|
||||
return mapValues(pick(VALID_SCHEMA_PROPERTIES), schemas) as Utils.StringRecord<Schema.Schema>;
|
||||
export const mapSchemasValues = (schemas: Utils.String.Dict<Schema.Schema>) => {
|
||||
return mapValues(pick(VALID_SCHEMA_PROPERTIES), schemas) as Utils.String.Dict<Schema.Schema>;
|
||||
};
|
||||
|
||||
@ -25,7 +25,7 @@ export type Configurable = { configurable: true };
|
||||
export type NonConfigurable = { configurable: false };
|
||||
|
||||
// custom field
|
||||
export type CustomField<T extends string, P extends object = undefined> = {
|
||||
export type CustomField<T extends string, P extends object | undefined = undefined> = {
|
||||
customField: T;
|
||||
options?: P;
|
||||
};
|
||||
@ -46,7 +46,7 @@ export type DefaultTo<T> = { default: T };
|
||||
export type Any =
|
||||
| Attribute.BigInteger
|
||||
| Attribute.Boolean
|
||||
| Attribute.Component<unknown, boolean>
|
||||
| Attribute.Component<Common.UID.Component, boolean>
|
||||
| Attribute.DateTime
|
||||
| Attribute.Date
|
||||
| Attribute.Decimal
|
||||
@ -56,7 +56,7 @@ export type Any =
|
||||
| Attribute.Float
|
||||
| Attribute.Integer
|
||||
| Attribute.JSON
|
||||
| Attribute.Media<unknown, boolean>
|
||||
| Attribute.Media<Attribute.AllowedMediaTypes | undefined, boolean>
|
||||
| Attribute.Password
|
||||
| Attribute.Relation
|
||||
| Attribute.RichText
|
||||
@ -64,4 +64,4 @@ export type Any =
|
||||
| Attribute.Text
|
||||
| Attribute.Time
|
||||
| Attribute.Timestamp
|
||||
| Attribute.UID<unknown>;
|
||||
| Attribute.UID<Common.UID.Schema | undefined>;
|
||||
|
||||
@ -14,7 +14,7 @@ export type DynamicZone<T extends Common.UID.Component[] = Common.UID.Component[
|
||||
Attribute.RequiredOption;
|
||||
|
||||
type DynamicZoneValue<T extends Common.UID.Component[]> = Array<
|
||||
Utils.GetArrayValues<T> extends infer P
|
||||
Utils.Array.Values<T> extends infer P
|
||||
? P extends Common.UID.ContentType
|
||||
? Attribute.GetValues<P> & { __component: P }
|
||||
: never
|
||||
|
||||
@ -12,7 +12,7 @@ export type Enumeration<T extends string[] = []> = Attribute.Attribute<'enumerat
|
||||
Attribute.PrivateOption &
|
||||
Attribute.RequiredOption;
|
||||
|
||||
export type EnumerationValue<T extends string[]> = Utils.GetArrayValues<T>;
|
||||
export type EnumerationValue<T extends string[]> = Utils.Array.Values<T>;
|
||||
|
||||
export type GetEnumerationValue<T extends Attribute.Attribute> = T extends Enumeration<infer U>
|
||||
? EnumerationValue<U>
|
||||
|
||||
@ -19,7 +19,7 @@ export type BasicRelationProperties<
|
||||
target: T;
|
||||
} & R extends `morph${string}`
|
||||
? {
|
||||
morphBy?: Utils.KeysBy<
|
||||
morphBy?: Utils.Object.KeysBy<
|
||||
Common.Schemas[T]['attributes'],
|
||||
Attribute.Relation<Common.UID.Schema, Attribute.PolymorphicRelationsType>
|
||||
>;
|
||||
@ -41,7 +41,9 @@ export type Relation<
|
||||
// Properties
|
||||
(R extends BasicRelationsType
|
||||
? BasicRelationProperties<S, R, T>
|
||||
: PolymorphicRelationProperties<R>) &
|
||||
: R extends PolymorphicRelationsType
|
||||
? PolymorphicRelationProperties<R>
|
||||
: {}) &
|
||||
// Options
|
||||
Attribute.ConfigurableOption &
|
||||
Attribute.PrivateOption;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { Attribute, Common } from '@strapi/strapi';
|
||||
import type { Attribute, Common, Utils } from '@strapi/strapi';
|
||||
|
||||
export interface UIDOptions {
|
||||
separator?: string;
|
||||
@ -10,13 +10,18 @@ export interface UIDOptions {
|
||||
|
||||
export interface UIDProperties<
|
||||
// Own Schema Reference
|
||||
T extends Common.UID.Schema | undefined,
|
||||
T extends Common.UID.Schema,
|
||||
// Target attribute
|
||||
U extends T extends Common.UID.Schema ? Attribute.GetKeysByType<T, 'string' | 'text'> : undefined,
|
||||
U extends TargetAttributeByUID<T>,
|
||||
// UID options
|
||||
S extends UIDOptions = UIDOptions
|
||||
> {
|
||||
targetField: U extends undefined ? string | undefined : U;
|
||||
targetField: U;
|
||||
options: UIDOptions & S;
|
||||
}
|
||||
|
||||
export interface GenericUIDProperties<S extends UIDOptions = UIDOptions> {
|
||||
targetField?: string;
|
||||
options: UIDOptions & S;
|
||||
}
|
||||
|
||||
@ -29,7 +34,7 @@ export type UID<
|
||||
S extends UIDOptions = UIDOptions
|
||||
> = Attribute.Attribute<'uid'> &
|
||||
// Properties
|
||||
UIDProperties<T, U, S> &
|
||||
(T extends Common.UID.Schema ? UIDProperties<T, U, S> : GenericUIDProperties<S>) &
|
||||
// Options
|
||||
Attribute.ConfigurableOption &
|
||||
Attribute.DefaultOption<UIDValue> &
|
||||
@ -38,8 +43,8 @@ export type UID<
|
||||
Attribute.RequiredOption;
|
||||
|
||||
type TargetAttributeByUID<T extends Common.UID.Schema | undefined> = T extends Common.UID.Schema
|
||||
? Attribute.GetKeysByType<T, 'string' | 'text'>
|
||||
: undefined;
|
||||
? Utils.Guard.Never<Attribute.GetKeysByType<T, 'string' | 'text'>, string>
|
||||
: never;
|
||||
|
||||
export type UIDValue = string;
|
||||
|
||||
|
||||
@ -6,13 +6,13 @@ export type GetKeysByType<
|
||||
T extends Common.UID.Schema,
|
||||
U extends Attribute.Type,
|
||||
P = never
|
||||
> = Utils.KeysBy<GetAll<T>, Attribute.Attribute<U> & Utils.NeverGuard<P, unknown>>;
|
||||
> = Utils.Object.KeysBy<GetAll<T>, Attribute.Attribute<U> & Utils.Guard.Never<P, unknown>>;
|
||||
|
||||
export type GetByType<
|
||||
T extends Common.UID.Schema,
|
||||
U extends Attribute.Type,
|
||||
P = never
|
||||
> = Utils.PickBy<GetAll<T>, Attribute.Attribute<U> & Utils.NeverGuard<P, unknown>>;
|
||||
> = Utils.Object.PickBy<GetAll<T>, Attribute.Attribute<U> & Utils.Guard.Never<P, unknown>>;
|
||||
|
||||
export type Get<T extends Common.UID.Schema, U extends GetKeys<T>> = Utils.Get<GetAll<T>, U>;
|
||||
|
||||
@ -60,7 +60,7 @@ export type GetValues<T extends Common.UID.Schema, U extends GetKeys<T> = GetKey
|
||||
[key in GetOptionalKeys<T> as key extends U ? key : never]?: GetValueByKey<T, key>;
|
||||
};
|
||||
|
||||
export type GetRequiredKeys<T extends Common.UID.Schema> = Utils.KeysBy<
|
||||
export type GetRequiredKeys<T extends Common.UID.Schema> = Utils.Object.KeysBy<
|
||||
GetAll<T>,
|
||||
{ required: true }
|
||||
>;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import type koa from 'koa';
|
||||
import type { ExtendableContext, Next } from 'koa';
|
||||
|
||||
export type ControllerHandler = <T>(
|
||||
context: koa.ExtendableContext,
|
||||
next: koa.Next
|
||||
context: ExtendableContext,
|
||||
next: Next
|
||||
) => Promise<T | void> | T | void;
|
||||
|
||||
export type Controller = Record<string, ControllerHandler>;
|
||||
|
||||
@ -17,11 +17,11 @@ export type Middleware = Registry.Keys<Shared.Middlewares, UID.Middleware>;
|
||||
|
||||
export type ContentType = Registry.Keys<Shared.ContentTypes, UID.ContentType>;
|
||||
export type CollectionType = Extract<
|
||||
Utils.KeysBy<Shared.ContentTypes, SchemaNamespace.CollectionType>,
|
||||
Utils.Object.KeysBy<Shared.ContentTypes, SchemaNamespace.CollectionType>,
|
||||
ContentType
|
||||
>;
|
||||
export type SingleType = Extract<
|
||||
Utils.KeysBy<Shared.ContentTypes, SchemaNamespace.SingleType>,
|
||||
Utils.Object.KeysBy<Shared.ContentTypes, SchemaNamespace.SingleType>,
|
||||
ContentType
|
||||
>;
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ export type GetSeparator<T extends Any = Any> = T extends Scoped
|
||||
* type T = WithSeparator<Admin> | WithSeparator<API>
|
||||
* // ^ 'admin::' | 'api::{string}.'
|
||||
*/
|
||||
export type WithSeparator<N extends Any> = Utils.Suffix<N, GetSeparator<N>>;
|
||||
export type WithSeparator<N extends Any> = Utils.String.Suffix<N, GetSeparator<N>>;
|
||||
|
||||
/**
|
||||
* Represents namespaces composed of an origin and a name, separated by colons
|
||||
|
||||
@ -78,7 +78,9 @@ export interface Info {
|
||||
/**
|
||||
* Low level data structure referencing every schema attribute and its name
|
||||
*/
|
||||
export interface Attributes extends Utils.StringRecord<Attribute.Any> {}
|
||||
export interface Attributes {
|
||||
[key: string]: Attribute.Any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure containing every core schema options and their associated value
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import type Koa from 'koa';
|
||||
import { Database } from '@strapi/database';
|
||||
|
||||
import type { StringMap } from './utils';
|
||||
import type { Shared } from '@strapi/strapi';
|
||||
import type { GenericController } from '../../../core-api/controller';
|
||||
import type { GenericService } from '../../../core-api/service';
|
||||
|
||||
@ -21,7 +20,7 @@ interface CustomFieldServerOptions {
|
||||
* The existing Strapi data type the custom field uses
|
||||
*/
|
||||
type: string;
|
||||
|
||||
|
||||
/**
|
||||
* Settings for the input size in the Admin UI
|
||||
*/
|
||||
@ -69,7 +68,7 @@ export interface Strapi {
|
||||
*
|
||||
* It returns all the registered services
|
||||
*/
|
||||
readonly services: StringMap<GenericService>;
|
||||
readonly services: Shared.Services;
|
||||
|
||||
/**
|
||||
* Find a service using its unique identifier
|
||||
@ -81,7 +80,7 @@ export interface Strapi {
|
||||
*
|
||||
* It returns all the registered controllers
|
||||
*/
|
||||
readonly controllers: StringMap<GenericController>;
|
||||
readonly controllers: Shared.Controllers;
|
||||
|
||||
/**
|
||||
* Find a controller using its unique identifier
|
||||
|
||||
2
packages/core/strapi/lib/types/core/uid.d.ts
vendored
2
packages/core/strapi/lib/types/core/uid.d.ts
vendored
@ -1,7 +1,7 @@
|
||||
import type * as Namespace from './namespace';
|
||||
import type * as Utils from '../utils';
|
||||
|
||||
type StringSuffix<T extends string> = Utils.Suffix<T, string>;
|
||||
type StringSuffix<T extends string> = Utils.String.Suffix<T, string>;
|
||||
|
||||
/**
|
||||
* Template for services' unique identifier
|
||||
|
||||
121
packages/core/strapi/lib/types/utils.d.ts
vendored
121
packages/core/strapi/lib/types/utils.d.ts
vendored
@ -1,121 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Common utilities used across Strapi typings
|
||||
*
|
||||
* */
|
||||
|
||||
/**
|
||||
* Alias for any literal type (useful for template string parameters)
|
||||
*/
|
||||
export type Literal = string | number | bigint | boolean;
|
||||
|
||||
/**
|
||||
* Used to check if a string includes a given literal
|
||||
*/
|
||||
export type Includes<S extends Literal> = `${string}${S}${string}`;
|
||||
|
||||
/**
|
||||
* Used to make sure the given string is not empty
|
||||
*/
|
||||
export type NonEmpty<T extends string> = T extends '' ? never : T;
|
||||
|
||||
/**
|
||||
* Split the given string into a tuple using the given `S` literal
|
||||
*/
|
||||
export type Split<T extends string, S extends Literal> = T extends `${infer A}${S}${infer B}`
|
||||
? [A, ...Split<B, S>]
|
||||
: T extends ''
|
||||
? []
|
||||
: [T];
|
||||
|
||||
/**
|
||||
* Aggregate the given tuple into a string, separated by the given `S` literal
|
||||
*/
|
||||
export type Join<T extends unknown[], S extends Literal> = T extends [
|
||||
infer F extends Literal,
|
||||
...infer R
|
||||
]
|
||||
? R['length'] extends 0
|
||||
? F
|
||||
: `${F}${S}${Join<R, S>}`
|
||||
: never;
|
||||
|
||||
/**
|
||||
* Add a literal suffix (`S`) at the end of the given string
|
||||
*/
|
||||
export type Suffix<T extends string, S extends Literal> = `${T}${S}`;
|
||||
|
||||
/**
|
||||
* Add a literal prefix (`S`) at the beginning of the given string
|
||||
*/
|
||||
export type Prefix<T extends string, S extends Literal> = `${S}${T}`;
|
||||
|
||||
/**
|
||||
*
|
||||
* Extract the array values into an union type
|
||||
*
|
||||
**/
|
||||
export type GetArrayValues<T extends Array<unknown>> = T extends Array<infer U> ? U : never;
|
||||
|
||||
/**
|
||||
* Creates a record where every key is a string and every value is `T`
|
||||
*/
|
||||
export type StringRecord<T> = Record<string, T>;
|
||||
|
||||
/**
|
||||
* Retrieve object's (`T`) keys if they extends the given `U` type.
|
||||
*
|
||||
* @example
|
||||
* type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string>
|
||||
* // 'foo' | 'bar'
|
||||
*
|
||||
* type Base = { x: 'foo' | 'bar' };
|
||||
* type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } };
|
||||
* type X = KeysBy<Obj, Base>
|
||||
* // 'foo' | 'bar'
|
||||
*/
|
||||
export type KeysBy<T, U> = {
|
||||
[key in keyof T]: T[key] extends U ? key : never;
|
||||
}[keyof T];
|
||||
|
||||
/**
|
||||
* Retrieve object's (`T`) properties if their value extends the given `U` type.
|
||||
*
|
||||
* @example
|
||||
* type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string>
|
||||
* // { foo: 'bar', bar: 'foo' }
|
||||
*
|
||||
* type Base = { x: 'foo' | 'bar' };
|
||||
* type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } };
|
||||
* type X = KeysBy<Obj, Base>
|
||||
* // { foo: { x: 'foo' }, bar: { x: 'bar' } }
|
||||
*/
|
||||
export type PickBy<T, U> = Pick<T, KeysBy<T, U>>;
|
||||
|
||||
/**
|
||||
* Assign a default value `U` to `T` if `T` is of type `never`
|
||||
*
|
||||
* @example
|
||||
* type X = NeverGuard<{ foo: 'bar' }, string>
|
||||
* // { foo: 'bar' }
|
||||
*
|
||||
* type X = NeverGuard<never>
|
||||
* // unknown
|
||||
*
|
||||
* type X = NeverGuard<never, string>
|
||||
* // string
|
||||
*/
|
||||
export type NeverGuard<T, U = unknown> = [T] extends [never] ? U : T;
|
||||
|
||||
/**
|
||||
* Get the type of a specific key `U` in `T`
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'foo'>
|
||||
* // 'bar'
|
||||
*
|
||||
* type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'bar'>
|
||||
* // 'foo'
|
||||
*/
|
||||
export type Get<T, U extends keyof T> = T[U];
|
||||
6
packages/core/strapi/lib/types/utils/array.d.ts
vendored
Normal file
6
packages/core/strapi/lib/types/utils/array.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
*
|
||||
* Extract the array values into an union type
|
||||
*
|
||||
**/
|
||||
export type Values<T extends Array<unknown>> = T extends Array<infer U> ? U : never;
|
||||
14
packages/core/strapi/lib/types/utils/guard.d.ts
vendored
Normal file
14
packages/core/strapi/lib/types/utils/guard.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Assign a default value `U` to `T` if `T` is of type `never`
|
||||
*
|
||||
* @example
|
||||
* type X = Never<{ foo: 'bar' }, string>
|
||||
* // { foo: 'bar' }
|
||||
*
|
||||
* type X = Never<never>
|
||||
* // unknown
|
||||
*
|
||||
* type X = Never<never, string>
|
||||
* // string
|
||||
*/
|
||||
export type Never<T, U = unknown> = [T] extends [never] ? U : T;
|
||||
18
packages/core/strapi/lib/types/utils/index.d.ts
vendored
Normal file
18
packages/core/strapi/lib/types/utils/index.d.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
export * as Array from './array';
|
||||
export * as Guard from './guard';
|
||||
export * as Object from './object';
|
||||
export * as String from './string';
|
||||
export * as Tuple from './tuple';
|
||||
|
||||
/**
|
||||
* Get the type of a specific key `U` in `T`
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'foo'>
|
||||
* // 'bar'
|
||||
*
|
||||
* type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'bar'>
|
||||
* // 'foo'
|
||||
*/
|
||||
export type Get<T, U extends keyof T> = T[U];
|
||||
29
packages/core/strapi/lib/types/utils/object.d.ts
vendored
Normal file
29
packages/core/strapi/lib/types/utils/object.d.ts
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Retrieve object's (`T`) keys if they extends the given `U` type.
|
||||
*
|
||||
* @example
|
||||
* type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string>
|
||||
* // 'foo' | 'bar'
|
||||
*
|
||||
* type Base = { x: 'foo' | 'bar' };
|
||||
* type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } };
|
||||
* type X = KeysBy<Obj, Base>
|
||||
* // 'foo' | 'bar'
|
||||
*/
|
||||
export type KeysBy<T, U> = {
|
||||
[key in keyof T]: T[key] extends U ? key : never;
|
||||
}[keyof T];
|
||||
|
||||
/**
|
||||
* Retrieve object's (`T`) properties if their value extends the given `U` type.
|
||||
*
|
||||
* @example
|
||||
* type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string>
|
||||
* // { foo: 'bar', bar: 'foo' }
|
||||
*
|
||||
* type Base = { x: 'foo' | 'bar' };
|
||||
* type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } };
|
||||
* type X = KeysBy<Obj, Base>
|
||||
* // { foo: { x: 'foo' }, bar: { x: 'bar' } }
|
||||
*/
|
||||
export type PickBy<T, U> = Pick<T, KeysBy<T, U>>;
|
||||
38
packages/core/strapi/lib/types/utils/string.d.ts
vendored
Normal file
38
packages/core/strapi/lib/types/utils/string.d.ts
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Alias for any literal type (useful for template string parameters)
|
||||
*/
|
||||
export type Literal = string | number | bigint | boolean;
|
||||
|
||||
/**
|
||||
* Used to check if a string includes a given literal
|
||||
*/
|
||||
export type Includes<S extends Literal> = `${string}${S}${string}`;
|
||||
|
||||
/**
|
||||
* Used to make sure the given string is not empty
|
||||
*/
|
||||
export type NonEmpty<T extends string> = T extends '' ? never : T;
|
||||
|
||||
/**
|
||||
* Split the given string into a tuple using the given `S` literal
|
||||
*/
|
||||
export type Split<T extends string, S extends Literal> = T extends `${infer A}${S}${infer B}`
|
||||
? [A, ...Split<B, S>]
|
||||
: T extends ''
|
||||
? []
|
||||
: [T];
|
||||
|
||||
/**
|
||||
* Add a literal suffix (`S`) at the end of the given string
|
||||
*/
|
||||
export type Suffix<T extends string, S extends Literal> = `${T}${S}`;
|
||||
|
||||
/**
|
||||
* Add a literal prefix (`S`) at the beginning of the given string
|
||||
*/
|
||||
export type Prefix<T extends string, S extends Literal> = `${S}${T}`;
|
||||
|
||||
/**
|
||||
* Creates a record where every key is a string and every value is `T`
|
||||
*/
|
||||
export type Dict<T> = Record<string, T>;
|
||||
13
packages/core/strapi/lib/types/utils/tuple.d.ts
vendored
Normal file
13
packages/core/strapi/lib/types/utils/tuple.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
import type { Literal } from './string';
|
||||
|
||||
/**
|
||||
* Aggregate the given tuple into a string, separated by the given `S` literal
|
||||
*/
|
||||
export type Join<T extends unknown[], S extends Literal> = T extends [
|
||||
infer F extends Literal,
|
||||
...infer R
|
||||
]
|
||||
? R['length'] extends 0
|
||||
? F
|
||||
: `${F}${S}${Join<R, S>}`
|
||||
: never;
|
||||
Loading…
x
Reference in New Issue
Block a user