-
-
Notifications
You must be signed in to change notification settings - Fork 677
Expand file tree
/
Copy pathremove-prefix.d.ts
More file actions
132 lines (99 loc) · 4.2 KB
/
remove-prefix.d.ts
File metadata and controls
132 lines (99 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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 {Or} from './or.d.ts';
/**
@see {@link RemovePrefix}
*/
export type RemovePrefixOptions = {
/**
When enabled, instantiations with non-literal prefixes (e.g., `string`, `Uppercase<string>`, `` `on${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, ``RemovePrefix<'on-change', `${string}-`, {strict: false}>`` returns `'change'`, but at runtime, prefix could be `'handle-'` (which satisfies `` `${string}-` ``) and removing `'handle-'` from `'on-change'` would not result in `'change'`.
So, it is recommended to not disable this option unless you are aware of the implications.
@default true
@example
```
import type {RemovePrefix} from 'type-fest';
type A = RemovePrefix<'on-change', `${string}-`, {strict: true}>;
//=> string
type B = RemovePrefix<'on-change', `${string}-`, {strict: false}>;
//=> 'change'
type C = RemovePrefix<'on-change', string, {strict: true}>;
//=> string
type D = RemovePrefix<'on-change', string, {strict: false}>;
//=> 'n-change'
type E = RemovePrefix<`${string}/${number}`, `${string}/`, {strict: true}>;
//=> string
type F = RemovePrefix<`${string}/${number}`, `${string}/`, {strict: false}>;
//=> `${number}`
```
Note: This option has no effect when only the input string type is non-literal. For example, ``RemovePrefix<`on-${string}`, 'on-'>`` will always return `string`.
@example
```
import type {RemovePrefix} from 'type-fest';
type A = RemovePrefix<`on-${string}`, 'on-', {strict: true}>;
//=> string
type B = RemovePrefix<`on-${string}`, 'on-', {strict: false}>;
//=> string
type C = RemovePrefix<`id-${number}`, 'id-', {strict: true}>;
//=> `${number}`
type D = RemovePrefix<`id-${number}`, 'id-', {strict: false}>;
//=> `${number}`
```
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'
```
*/
strict?: boolean;
};
type DefaultRemovePrefixOptions = {
strict: true;
};
/**
Remove the specified prefix from the start of a string.
@example
```
import type {RemovePrefix} from 'type-fest';
type A = RemovePrefix<'on-change', 'on-'>;
//=> 'change'
type B = RemovePrefix<'sm:flex' | 'sm:p-4' | 'sm:gap-2', 'sm:'>;
//=> 'flex' | 'p-4' | 'gap-2'
type C = RemovePrefix<'on-change', 'off-'>;
//=> 'on-change'
type D = RemovePrefix<`handle${Capitalize<string>}`, 'handle'>;
//=> Capitalize<string>
```
@see {@link RemovePrefixOptions}
@category String
@category Template literal
*/
export type RemovePrefix<S extends string, Prefix extends string, Options extends RemovePrefixOptions = {}> =
IfNotAnyOrNever<
S,
IfNotAnyOrNever<
Prefix,
_RemovePrefix<S, Prefix, ApplyDefaultOptions<RemovePrefixOptions, DefaultRemovePrefixOptions, Options>>,
string,
S
>
>;
type _RemovePrefix<S extends string, Prefix extends string, Options extends Required<RemovePrefixOptions>> =
Prefix extends string // For distributing `Prefix`
? S extends `${Prefix}${infer Rest}`
? Or<IsStringLiteral<Prefix>, Not<Options['strict']>> extends true
? 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`
: never;
export {};