type-fest
Advanced tools
| import type {ApplyDefaultOptions} from './internal/object.d.ts'; | ||
| import type {IfNotAnyOrNever, Not} from './internal/type.d.ts'; | ||
| import type {IsStringLiteral} from './is-literal.d.ts'; | ||
| import type {IsNever} from './is-never.d.ts'; | ||
| import type {Or} from './or.d.ts'; | ||
| import type {If} from './if.d.ts'; | ||
| /** | ||
| @see {@link RemoveSuffix} | ||
| */ | ||
| export type RemoveSuffixOptions = { | ||
| /** | ||
| When enabled, instantiations with non-literal suffixes (e.g., `string`, `Uppercase<string>`, `` `.${string}` ``) simply return `string`, since their precise structure cannot be statically determined. | ||
| Note: Disabling this option can produce misleading results that might not reflect the actual runtime behavior. | ||
| For example, ``RemoveSuffix<'report.pdf', `.${string}`, {strict: false}>`` returns `'report'`, but at runtime, suffix could be `'.txt'` (which satisfies `` `.${string}` ``) and removing `'.txt'` from `'report.pdf'` would not result in `'report'`. | ||
| So, it is recommended to not disable this option unless you are aware of the implications. | ||
| @default true | ||
| @example | ||
| ``` | ||
| import type {RemoveSuffix} from 'type-fest'; | ||
| type A = RemoveSuffix<'report.pdf', `.${string}`, {strict: true}>; | ||
| //=> string | ||
| type B = RemoveSuffix<'report.pdf', `.${string}`, {strict: false}>; | ||
| //=> 'report' | ||
| type C = RemoveSuffix<'on-change', string, {strict: true}>; | ||
| //=> string | ||
| type D = RemoveSuffix<'on-change', string, {strict: false}>; | ||
| //=> 'o' | ||
| type E = RemoveSuffix<`${number}/${string}`, `/${string}`, {strict: true}>; | ||
| //=> string | ||
| type F = RemoveSuffix<`${number}/${string}`, `/${string}`, {strict: false}>; | ||
| //=> `${number}` | ||
| ``` | ||
| Note: This option has no effect when only the input string type is non-literal. For example, ``RemoveSuffix<`${string}.pdf`, '.pdf'>`` will always return `string`. | ||
| @example | ||
| ``` | ||
| import type {RemoveSuffix} from 'type-fest'; | ||
| type A = RemoveSuffix<`${string}.pdf`, '.pdf', {strict: true}>; | ||
| //=> string | ||
| type B = RemoveSuffix<`${string}.pdf`, '.pdf', {strict: false}>; | ||
| //=> string | ||
| type C = RemoveSuffix<`${number}px`, 'px', {strict: true}>; | ||
| //=> `${number}` | ||
| type D = RemoveSuffix<`${number}px`, 'px', {strict: false}>; | ||
| //=> `${number}` | ||
| ``` | ||
| */ | ||
| strict?: boolean; | ||
| }; | ||
| type DefaultRemoveSuffixOptions = { | ||
| strict: true; | ||
| }; | ||
| /** | ||
| Remove the specified suffix from the end of a string. | ||
| @example | ||
| ``` | ||
| import type {RemoveSuffix} from 'type-fest'; | ||
| type A = RemoveSuffix<'report.pdf', '.pdf'>; | ||
| //=> 'report' | ||
| type B = RemoveSuffix<'bg-blue-500' | 'text-green-500' | 'border-slate-500', '-500'>; | ||
| //=> 'bg-blue' | 'border-slate' | 'text-green' | ||
| type C = RemoveSuffix<'report.pdf', '.txt'>; | ||
| //=> 'report.pdf' | ||
| type D = RemoveSuffix<`api/${string}/analytics`, '/analytics'>; | ||
| //=> `api/${string}` | ||
| ``` | ||
| @see {@link RemoveSuffixOptions} | ||
| @category String | ||
| @category Template literal | ||
| */ | ||
| export type RemoveSuffix<S extends string, Suffix extends string, Options extends RemoveSuffixOptions = {}> = | ||
| IfNotAnyOrNever< | ||
| S, | ||
| If< | ||
| IsNever<Suffix>, | ||
| S, | ||
| _RemoveSuffix<S, Suffix, ApplyDefaultOptions<RemoveSuffixOptions, DefaultRemoveSuffixOptions, Options>> | ||
| > | ||
| >; | ||
| type _RemoveSuffix<S extends string, Suffix extends string, Options extends Required<RemoveSuffixOptions>> = | ||
| Suffix extends string // For distributing `Suffix` | ||
| ? Or<IsStringLiteral<Suffix>, Not<Options['strict']>> extends true | ||
| ? S extends `${infer Rest}${Suffix}` | ||
| ? Rest | ||
| : S // Return back `S` when `Suffix` is not present at the end of `S` | ||
| : string // Fallback to `string` when `Suffix` is non-literal and `strict` is enabled | ||
| : never; | ||
| export {}; |
| import type {MapsSetsOrArrays, NonRecursiveType} from './internal/type.d.ts'; | ||
| /** | ||
| Revert the `Required` modifier on an object type. | ||
| Use-case: Infer the underlying type `T` when only `Required<T>` is available or the original type may not be directly accessible. | ||
| @example | ||
| ``` | ||
| import type {UnwrapRequired} from 'type-fest'; | ||
| type ContactFormData = Required<{ | ||
| email: string; | ||
| message?: string; | ||
| }>; | ||
| type DraftContactFormData = UnwrapRequired<ContactFormData>; | ||
| //=> {email: string; message?: string} | ||
| ``` | ||
| Note: | ||
| - If the provided type isn’t of the form `Required<T>`, `UnwrapRequired` simply returns the input type. | ||
| - `UnwrapRequired` doesn't work with arrays, if instantiated with arrays, it simply returns the input type. | ||
| @category Object | ||
| */ | ||
| export type UnwrapRequired<RequiredObjectType> = | ||
| RequiredObjectType extends NonRecursiveType | MapsSetsOrArrays | ||
| ? RequiredObjectType | ||
| : _UnwrapRequired<RequiredObjectType>; | ||
| type _UnwrapRequired<RequiredObjectType> = | ||
| RequiredObjectType extends Required<infer ObjectType> | ||
| ? ObjectType | ||
| : RequiredObjectType; | ||
| export {}; |
+3
-1
@@ -37,2 +37,3 @@ // Basic | ||
| export type {UnwrapPartial} from './source/unwrap-partial.d.ts'; | ||
| export type {UnwrapRequired} from './source/unwrap-required.d.ts'; | ||
| export type {RequiredDeep} from './source/required-deep.d.ts'; | ||
@@ -210,2 +211,3 @@ export type {PickDeep} from './source/pick-deep.d.ts'; | ||
| export type {RemovePrefix, RemovePrefixOptions} from './source/remove-prefix.d.ts'; | ||
| export type {RemoveSuffix, RemoveSuffixOptions} from './source/remove-suffix.d.ts'; | ||
@@ -218,3 +220,3 @@ // Miscellaneous | ||
| // Improved built-in | ||
| export type {ExtendsStrict} from './source/extends-strict.d.ts'; | ||
| export type {ExtendsStrict, ExtendsStrictOptions} from './source/extends-strict.d.ts'; | ||
| export type {ExtractStrict} from './source/extract-strict.d.ts'; | ||
@@ -221,0 +223,0 @@ export type {ExcludeStrict} from './source/exclude-strict.d.ts'; |
+1
-1
| { | ||
| "name": "type-fest", | ||
| "version": "5.6.0", | ||
| "version": "5.7.0", | ||
| "description": "A collection of essential TypeScript types", | ||
@@ -5,0 +5,0 @@ "license": "(MIT OR CC0-1.0)", |
+5
-1
@@ -138,2 +138,3 @@ <div align="center"> | ||
| - [`UnwrapPartial`](source/unwrap-partial.d.ts) - Revert the `Partial` modifier on an object type. | ||
| - [`UnwrapRequired`](source/unwrap-required.d.ts) - Revert the `Required` modifier on an object type. | ||
| - [`ReadonlyDeep`](source/readonly-deep.d.ts) - Create a deeply immutable version of another type. | ||
@@ -267,2 +268,3 @@ - [`LiteralUnion`](source/literal-union.d.ts) - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. | ||
| - [`RemovePrefix`](source/remove-prefix.d.ts) - Remove the specified prefix from the start of a string. | ||
| - [`RemoveSuffix`](source/remove-suffix.d.ts) - Remove the specified suffix from the end of a string. | ||
@@ -341,3 +343,3 @@ ### Array | ||
| - [`ExtendsStrict`](source/extends-strict.d.ts) - A stricter, non-distributive version of `extends` for checking whether one type is assignable to another. | ||
| - [`ExtendsStrict`](source/extends-strict.d.ts) - A customizable version of `extends` for checking whether one type is assignable to another. | ||
| - [`ExtractStrict`](source/extract-strict.d.ts) - A stricter version of `Extract<T, U>` that ensures every member of `U` can successfully extract something from `T`. | ||
@@ -540,2 +542,4 @@ - [`ExcludeStrict`](source/exclude-strict.d.ts) - A stricter version of `Exclude<T, U>` that ensures every member of `U` can successfully exclude something from `T`. | ||
| ``` | ||
| `Required<T>` can be reverted with [`UnwrapRequired`](source/unwrap-required.d.ts). | ||
| </details> | ||
@@ -542,0 +546,0 @@ |
| import type {ApplyDefaultOptions, AsciiPunctuation, StartsWith} from './internal/index.d.ts'; | ||
| import type {IsStringLiteral} from './is-literal.d.ts'; | ||
| import type {Merge} from './merge.d.ts'; | ||
| import type {RemovePrefix} from './remove-prefix.d.ts'; | ||
| import type {_DefaultWordsOptions, Words, WordsOptions} from './words.d.ts'; | ||
@@ -20,3 +19,3 @@ | ||
| ] | ||
| ? DelimiterCaseFromArray<RemainingWords, Delimiter, `${OutputString}${ | ||
| ? DelimiterCaseFromArray<RemainingWords, Delimiter, OutputString extends '' ? FirstWord : `${OutputString}${ | ||
| StartsWith<FirstWord, AsciiPunctuation> extends true ? '' : Delimiter | ||
@@ -71,10 +70,12 @@ }${FirstWord}`> | ||
| > = Value extends string | ||
| ? IsStringLiteral<Value> extends false | ||
| ? Value | ||
| : Lowercase<RemovePrefix<DelimiterCaseFromArray< | ||
| Words<Value, ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>, | ||
| Delimiter | ||
| >, string, {strict: false}>> | ||
| ? Delimiter extends string // For distributing `Delimiter` | ||
| ? IsStringLiteral<Value> extends false | ||
| ? Value | ||
| : Lowercase<DelimiterCaseFromArray< | ||
| Words<Value, ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>, | ||
| Delimiter | ||
| >> | ||
| : never | ||
| : Value; | ||
| export {}; |
+129
-22
| import type {IsNever} from './is-never.d.ts'; | ||
| import type {IsAny} from './is-any.d.ts'; | ||
| import type {ApplyDefaultOptions} from './internal/object.d.ts'; | ||
| import type {And} from './and.d.ts'; | ||
| import type {Or} from './or.d.ts'; | ||
| import type {IsUnknown} from './is-unknown.d.ts'; | ||
| import type {OrAll} from './or-all.d.ts'; | ||
| /** | ||
| A stricter, non-distributive version of `extends` for checking whether one type is assignable to another. | ||
| export type ExtendsStrictOptions = { | ||
| /** | ||
| Whether to distribute over unions. | ||
| Unlike the built-in `extends` keyword, `ExtendsStrict`: | ||
| @default false | ||
| 1. Prevents distribution over union types by wrapping both types in tuples. For example, `ExtendsStrict<string | number, number>` returns `false`, whereas `string | number extends number` would result in `boolean`. | ||
| @example | ||
| ``` | ||
| import type {ExtendsStrict} from 'type-fest'; | ||
| 2. Treats `never` as a special case: `never` doesn't extend every other type, it only extends itself (or `any`). For example, `ExtendsStrict<never, number>` returns `false` whereas `never extends number` would result in `true`. | ||
| type T1 = ExtendsStrict<string | number, string, {distributiveUnions: true}>; | ||
| //=> boolean | ||
| type T2 = ExtendsStrict<string | number, string, {distributiveUnions: false}>; | ||
| //=> false | ||
| ``` | ||
| */ | ||
| distributiveUnions?: boolean; | ||
| /** | ||
| Whether `never` extends every other type. | ||
| When enabled, `never` is not treated as a bottom type and only extends itself (or `any` / `unknown`). | ||
| @default true | ||
| @example | ||
| ``` | ||
| import type {ExtendsStrict} from 'type-fest'; | ||
| type T1 = ExtendsStrict<never, number, {strictNever: true}>; | ||
| //=> false | ||
| type T2 = ExtendsStrict<never, number, {strictNever: false}>; | ||
| //=> true | ||
| type T3 = ExtendsStrict<never, never, {strictNever: true}>; | ||
| //=> true | ||
| type T4 = ExtendsStrict<never, any, {strictNever: true}>; | ||
| //=> true | ||
| type T5 = ExtendsStrict<never, unknown, {strictNever: true}>; | ||
| //=> true | ||
| ``` | ||
| Note: This option only has an effect when checking assignability from `never` (`ExtendsStrict<never, ...>`), and not when checking assignability to `never` (`ExtendsStrict<..., never>`). | ||
| */ | ||
| strictNever?: boolean; | ||
| /** | ||
| Whether `any` extends every other type. | ||
| When enabled, `any` does not extend every other type, it only extends itself (or `unknown`). | ||
| @default false | ||
| @example | ||
| ``` | ||
| import type {ExtendsStrict} from 'type-fest'; | ||
| type T1 = ExtendsStrict<any, number, {strictAny: true}>; | ||
| //=> false | ||
| type T2 = ExtendsStrict<any, number, {strictAny: false; distributiveUnions: false}>; | ||
| //=> true | ||
| type T3 = ExtendsStrict<any, any, {strictAny: true}>; | ||
| //=> true | ||
| type T4 = ExtendsStrict<any, unknown, {strictAny: true}>; | ||
| //=> true | ||
| ``` | ||
| Note: If `strictAny` is `false` and `distributiveUnions` is `true`, then `any` would distribute and the result would be the `boolean` type, except when checking assignability to `any` or `unknown`. | ||
| @example | ||
| ``` | ||
| import type {ExtendsStrict} from 'type-fest'; | ||
| type T1 = ExtendsStrict<any, number, {strictAny: false; distributiveUnions: true}>; | ||
| //=> boolean | ||
| type T2 = ExtendsStrict<any, any, {strictAny: false; distributiveUnions: true}>; | ||
| //=> true | ||
| type T3 = ExtendsStrict<any, unknown, {strictAny: false; distributiveUnions: true}>; | ||
| //=> true | ||
| ``` | ||
| Note: This option only has an effect when checking assignability from `any` (`ExtendsStrict<any, ...>`), and not when checking assignability to `any` (`ExtendsStrict<..., any>`). | ||
| */ | ||
| strictAny?: boolean; | ||
| }; | ||
| type DefaultExtendsStrictOptions = { | ||
| distributiveUnions: false; | ||
| strictNever: true; | ||
| strictAny: false; | ||
| }; | ||
| /** | ||
| A customizable version of `extends` for checking whether one type is assignable to another. | ||
| Refer {@link ExtendsStrictOptions} for the different ways you can customize the behavior of this type. | ||
| @example | ||
@@ -17,29 +119,34 @@ ``` | ||
| type T1 = ExtendsStrict<number | string, string>; | ||
| type T1 = ExtendsStrict<number | string, string, {distributiveUnions: false}>; | ||
| //=> false | ||
| type T2 = ExtendsStrict<never, number>; | ||
| type T2 = ExtendsStrict<never, number, {strictNever: true}>; | ||
| //=> false | ||
| type T3 = ExtendsStrict<never, never>; | ||
| //=> true | ||
| type T3 = ExtendsStrict<any, number, {strictAny: true}>; | ||
| //=> false | ||
| ``` | ||
| type T4 = ExtendsStrict<string, number | string>; | ||
| //=> true | ||
| @see {@link ExtendsStrictOptions} | ||
| type T5 = ExtendsStrict<string, string>; | ||
| //=> true | ||
| ``` | ||
| @category Improved Built-in | ||
| */ | ||
| export type ExtendsStrict<Left, Right> = | ||
| IsAny<Left | Right> extends true | ||
| ? true | ||
| export type ExtendsStrict<Left, Right, Options extends ExtendsStrictOptions = {}> = | ||
| _ExtendsStrict<Left, Right, ApplyDefaultOptions<ExtendsStrictOptions, DefaultExtendsStrictOptions, Options>>; | ||
| type _ExtendsStrict<Left, Right, Options extends Required<ExtendsStrictOptions>> = | ||
| And<IsAny<Left>, Options['strictAny']> extends true | ||
| ? Or<IsAny<Right>, IsUnknown<Right>> | ||
| : IsNever<Left> extends true | ||
| ? IsNever<Right> | ||
| : [Left] extends [Right] | ||
| ? true | ||
| : false; | ||
| ? Options['strictNever'] extends true | ||
| ? OrAll<[IsNever<Right>, IsAny<Right>, IsUnknown<Right>]> | ||
| : true | ||
| : Options['distributiveUnions'] extends true | ||
| ? Left extends Right | ||
| ? true | ||
| : false | ||
| : [Left] extends [Right] | ||
| ? true | ||
| : false; | ||
| export {}; |
@@ -6,3 +6,2 @@ import type {Simplify} from '../simplify.d.ts'; | ||
| import type {Merge} from '../merge.d.ts'; | ||
| import type {OptionalKeysOf} from '../optional-keys-of.d.ts'; | ||
| import type {IsAny} from '../is-any.d.ts'; | ||
@@ -228,9 +227,18 @@ import type {If} from '../if.d.ts'; | ||
| > = | ||
| _ApplyDefaultOptions<Options, Defaults, SpecifiedOptions> extends infer Result extends Required<Options> // `extends Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>` | ||
| ? Result | ||
| : never; | ||
| type _ApplyDefaultOptions< | ||
| Options, | ||
| Defaults, | ||
| SpecifiedOptions, | ||
| > = | ||
| If<IsAny<SpecifiedOptions>, Defaults, | ||
| If<IsNever<SpecifiedOptions>, Defaults, | ||
| Simplify<Merge<Defaults, { | ||
| Merge<Defaults, { | ||
| [Key in keyof SpecifiedOptions | ||
| as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key | ||
| as undefined extends Required<Options>[Key & keyof Options] ? Key : undefined extends SpecifiedOptions[Key] ? never : Key | ||
| ]: SpecifiedOptions[Key] | ||
| }> & Required<Options>>>>; // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>` | ||
| }>>>; | ||
@@ -237,0 +245,0 @@ /** |
| import type {ApplyDefaultOptions} from './internal/object.d.ts'; | ||
| import type {IfNotAnyOrNever, Not} from './internal/type.d.ts'; | ||
| import type {IsStringLiteral} from './is-literal.d.ts'; | ||
| import type {IsNever} from './is-never.d.ts'; | ||
| import type {Or} from './or.d.ts'; | ||
| import type {If} from './if.d.ts'; | ||
@@ -61,20 +63,2 @@ /** | ||
| ``` | ||
| Note: If it can be statically determined that the input string can never start with the specified non-literal prefix, then the input string is returned as-is, regardless of the value of this option. | ||
| For example, ``RemovePrefix<`${string}/${number}`, `${string}:`>`` returns `` `${string}/${number}` ``, since a string of type `` `${string}/${number}` `` can never start with a prefix of type `` `${string}:` ``. | ||
| ``` | ||
| import type {RemovePrefix} from 'type-fest'; | ||
| type A = RemovePrefix<`${string}/${number}`, `${string}:`, {strict: true}>; | ||
| //=> `${string}/${number}` | ||
| type B = RemovePrefix<`${string}/${number}`, `${string}:`, {strict: false}>; | ||
| //=> `${string}/${number}` | ||
| type C = RemovePrefix<'on-change', `${number}-`, {strict: true}>; | ||
| //=> 'on-change' | ||
| type D = RemovePrefix<'on-change', `${number}-`, {strict: false}>; | ||
| //=> 'on-change' | ||
| ``` | ||
| */ | ||
@@ -116,7 +100,6 @@ strict?: boolean; | ||
| S, | ||
| IfNotAnyOrNever< | ||
| Prefix, | ||
| _RemovePrefix<S, Prefix, ApplyDefaultOptions<RemovePrefixOptions, DefaultRemovePrefixOptions, Options>>, | ||
| string, | ||
| S | ||
| If< | ||
| IsNever<Prefix>, | ||
| S, | ||
| _RemovePrefix<S, Prefix, ApplyDefaultOptions<RemovePrefixOptions, DefaultRemovePrefixOptions, Options>> | ||
| > | ||
@@ -127,9 +110,9 @@ >; | ||
| Prefix extends string // For distributing `Prefix` | ||
| ? S extends `${Prefix}${infer Rest}` | ||
| ? Or<IsStringLiteral<Prefix>, Not<Options['strict']>> extends true | ||
| ? Or<IsStringLiteral<Prefix>, Not<Options['strict']>> extends true | ||
| ? S extends `${Prefix}${infer Rest}` | ||
| ? Rest | ||
| : string // Fallback to `string` when `Prefix` is non-literal and `strict` is disabled | ||
| : S // Return back `S` when `Prefix` is not present at the start of `S` | ||
| : S // Return back `S` when `Prefix` is not present at the start of `S` | ||
| : string // Fallback to `string` when `Prefix` is non-literal and `strict` is enabled | ||
| : never; | ||
| export {}; |
+38
-6
| import type {If} from './if.d.ts'; | ||
| import type {IfNotAnyOrNever} from './internal/type.d.ts'; | ||
| import type {IsNegative} from './numeric.d.ts'; | ||
| import type {DigitCharacter} from './characters.d.ts'; | ||
| import type {UnknownArray} from './unknown-array.d.ts'; | ||
@@ -33,3 +34,3 @@ | ||
| type ThreeToEight = Range<3, 9>; | ||
| //=> '5' | '3' | '4' | '6' | '7' | '8' | ||
| //=> '3' | '4' | '5' | '6' | '7' | '8' | ||
| ``` | ||
@@ -67,2 +68,12 @@ | ||
| Note: If the specified length has a decimal part, the decimal part will be ignored. | ||
| @example | ||
| ``` | ||
| import type {TupleOf} from 'type-fest'; | ||
| type DecimalLength = TupleOf<3.5, string>; | ||
| //=> [string, string, string] | ||
| ``` | ||
| Note: If you need a readonly tuple, simply wrap this type with `Readonly`, for example, to create `readonly [number, number, number]` use `Readonly<TupleOf<3, number>>`. | ||
@@ -73,11 +84,32 @@ | ||
| export type TupleOf<Length extends number, Fill = unknown> = IfNotAnyOrNever<Length, | ||
| _TupleOf<If<IsNegative<Length>, 0, Length>, Fill, []>, | ||
| _TupleOf<If<IsNegative<Length>, 0, Length>, Fill>, | ||
| Fill[], []>; | ||
| type _TupleOf<L extends number, Fill, Accumulator extends UnknownArray> = number extends L | ||
| type _TupleOf<Length extends number, Fill> = number extends Length | ||
| ? Fill[] | ||
| : L extends Accumulator['length'] | ||
| ? Accumulator | ||
| : _TupleOf<L, Fill, [...Accumulator, Fill]>; | ||
| : BuildTupleDigitByDigit<`${Length}`, Fill>; | ||
| type BuildTupleDigitByDigit<Length extends string, Fill, Accumulator extends UnknownArray = []> = | ||
| Length extends `${infer First extends DigitCharacter}${infer Rest}` | ||
| ? BuildTupleDigitByDigit<Rest, Fill, [...RepeatTupleTenTimes<Accumulator>, ...DigitTupleOf<First, Fill>]> | ||
| : Accumulator; | ||
| type RepeatTupleTenTimes<Tuple extends UnknownArray> = [ | ||
| ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, | ||
| ...Tuple, ...Tuple, ...Tuple, ...Tuple, ...Tuple, | ||
| ]; | ||
| type DigitTupleOf<Digit extends DigitCharacter, Fill> = [ | ||
| [], | ||
| [Fill], | ||
| [Fill, Fill], | ||
| [Fill, Fill, Fill], | ||
| [Fill, Fill, Fill, Fill], | ||
| [Fill, Fill, Fill, Fill, Fill], | ||
| [Fill, Fill, Fill, Fill, Fill, Fill], | ||
| [Fill, Fill, Fill, Fill, Fill, Fill, Fill], | ||
| [Fill, Fill, Fill, Fill, Fill, Fill, Fill, Fill], | ||
| [Fill, Fill, Fill, Fill, Fill, Fill, Fill, Fill, Fill], | ||
| ][Digit]; | ||
| export {}; |
558867
1.52%212
0.95%13610
1.63%1082
0.37%