type-fest 1.1.2 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/package.json +1 -1
  2. package/readme.md +1 -0
  3. package/source/async-return-type.d.ts +2 -0
  4. package/source/asyncify.d.ts +2 -0
  5. package/source/basic.d.ts +8 -0
  6. package/source/conditional-except.d.ts +2 -0
  7. package/source/conditional-keys.d.ts +2 -0
  8. package/source/conditional-pick.d.ts +2 -0
  9. package/source/entries.d.ts +2 -0
  10. package/source/entry.d.ts +2 -0
  11. package/source/except.d.ts +2 -0
  12. package/source/fixed-length-array.d.ts +2 -0
  13. package/source/iterable-element.d.ts +2 -0
  14. package/source/literal-union.d.ts +2 -0
  15. package/source/merge-exclusive.d.ts +2 -0
  16. package/source/merge.d.ts +2 -0
  17. package/source/mutable.d.ts +3 -1
  18. package/source/observable-like.d.ts +2 -0
  19. package/source/opaque.d.ts +2 -0
  20. package/source/package-json.d.ts +2 -0
  21. package/source/partial-deep.d.ts +2 -0
  22. package/source/primitive.d.ts +2 -0
  23. package/source/promisable.d.ts +2 -0
  24. package/source/promise-value.d.ts +2 -0
  25. package/source/readonly-deep.d.ts +2 -0
  26. package/source/require-at-least-one.d.ts +2 -0
  27. package/source/require-exactly-one.d.ts +2 -0
  28. package/source/set-optional.d.ts +2 -0
  29. package/source/set-required.d.ts +2 -0
  30. package/source/set-return-type.d.ts +2 -0
  31. package/source/stringified.d.ts +2 -0
  32. package/source/tsconfig-json.d.ts +5 -0
  33. package/source/typed-array.d.ts +2 -0
  34. package/source/union-to-intersection.d.ts +2 -0
  35. package/source/value-of.d.ts +2 -0
  36. package/ts41/camel-case.d.ts +3 -1
  37. package/ts41/camel-cased-properties-deep.d.ts +2 -0
  38. package/ts41/camel-cased-properties.d.ts +2 -0
  39. package/ts41/delimiter-case.d.ts +4 -1
  40. package/ts41/delimiter-cased-properties-deep.d.ts +2 -0
  41. package/ts41/delimiter-cased-properties.d.ts +2 -0
  42. package/ts41/get.d.ts +2 -0
  43. package/ts41/index.d.ts +1 -0
  44. package/ts41/kebab-case.d.ts +2 -1
  45. package/ts41/kebab-cased-properties-deep.d.ts +2 -0
  46. package/ts41/kebab-cased-properties.d.ts +2 -0
  47. package/ts41/last-array-element.d.ts +2 -0
  48. package/ts41/pascal-case.d.ts +2 -1
  49. package/ts41/pascal-cased-properties-deep.d.ts +2 -0
  50. package/ts41/pascal-cased-properties.d.ts +2 -0
  51. package/ts41/screaming-snake-case.d.ts +40 -0
  52. package/ts41/snake-case.d.ts +2 -0
  53. package/ts41/snake-cased-properties-deep.d.ts +2 -0
  54. package/ts41/snake-cased-properties.d.ts +2 -0
  55. package/ts41/split.d.ts +10 -4
  56. package/ts41/trim.d.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "1.1.2",
3
+ "version": "1.2.2",
4
4
  "description": "A collection of essential TypeScript types",
5
5
  "license": "(MIT OR CC0-1.0)",
6
6
  "repository": "sindresorhus/type-fest",
package/readme.md CHANGED
@@ -136,6 +136,7 @@ Click the type names for complete docs.
136
136
  - [`SnakeCase`](ts41/snake-case.d.ts) – Convert a string literal to snake-case (`foo_bar`).
137
137
  - [`SnakeCasedProperties`](ts41/snake-cased-properties-deep.d.ts) – Convert object properties to snake-case (`foo_bar`).
138
138
  - [`SnakeCasedPropertiesDeep`](ts41/snake-cased-properties-deep.d.ts) – Convert object properties to snake-case recursively (`foo_bar`).
139
+ - [`ScreamingSnakeCase`](ts41/screaming-snake-case.d.ts) - Convert a string literal to screaming-snake-case (`FOO_BAR`).
139
140
  - [`DelimiterCase`](ts41/delimiter-case.d.ts) – Convert a string literal to a custom string delimiter casing.
140
141
  - [`DelimiterCasedProperties`](ts41/delimiter-cased-properties.d.ts) – Convert object properties to a custom string delimiter casing.
141
142
  - [`DelimiterCasedPropertiesDeep`](ts41/delimiter-cased-properties-deep.d.ts) – Convert object properties to a custom string delimiter casing recursively.
@@ -19,5 +19,7 @@ async function doSomething(value: Value) {}
19
19
 
20
20
  asyncFunction().then(value => doSomething(value));
21
21
  ```
22
+
23
+ @category Utilities
22
24
  */
23
25
  export type AsyncReturnType<Target extends AsyncFunction> = PromiseValue<ReturnType<Target>>;
@@ -27,5 +27,7 @@ const getFooAsync: AsyncifiedFooGetter = (someArg) => {
27
27
  // …
28
28
  }
29
29
  ```
30
+
31
+ @category Utilities
30
32
  */
31
33
  export type Asyncify<Fn extends (...args: any[]) => any> = SetReturnType<Fn, Promise<PromiseValue<ReturnType<Fn>>>>;
package/source/basic.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  // TODO: Remove the `= unknown` sometime in the future when most users are on TS 3.5 as it's now the default
2
2
  /**
3
3
  Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
4
+
5
+ @category Basic
4
6
  */
5
7
  export type Class<T = unknown, Arguments extends any[] = any[]> = new(...arguments_: Arguments) => T;
6
8
 
@@ -8,11 +10,15 @@ export type Class<T = unknown, Arguments extends any[] = any[]> = new(...argumen
8
10
  Matches a JSON object.
9
11
 
10
12
  This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`.
13
+
14
+ @category Basic
11
15
  */
12
16
  export type JsonObject = {[Key in string]?: JsonValue};
13
17
 
14
18
  /**
15
19
  Matches a JSON array.
20
+
21
+ @category Basic
16
22
  */
17
23
  export interface JsonArray extends Array<JsonValue> {}
18
24
  // TODO: Make it this when targeting TypeScript 4.1:
@@ -20,5 +26,7 @@ export interface JsonArray extends Array<JsonValue> {}
20
26
 
21
27
  /**
22
28
  Matches any valid JSON value.
29
+
30
+ @category Basic
23
31
  */
24
32
  export type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
@@ -36,6 +36,8 @@ interface Example {
36
36
  type NonStringKeysOnly = ConditionalExcept<Example, string>;
37
37
  //=> {b: string | number; c: () => void; d: {}}
38
38
  ```
39
+
40
+ @category Utilities
39
41
  */
40
42
  export type ConditionalExcept<Base, Condition> = Except<
41
43
  Base,
@@ -25,6 +25,8 @@ To support partial types, make sure your `Condition` is a union of undefined (fo
25
25
  type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>;
26
26
  //=> 'a' | 'c'
27
27
  ```
28
+
29
+ @category Utilities
28
30
  */
29
31
  export type ConditionalKeys<Base, Condition> = NonNullable<
30
32
  // Wrap in `NonNullable` to strip away the `undefined` type from the produced union.
@@ -35,6 +35,8 @@ interface Example {
35
35
  type StringKeysOnly = ConditionalPick<Example, string>;
36
36
  //=> {a: string}
37
37
  ```
38
+
39
+ @category Utilities
38
40
  */
39
41
  export type ConditionalPick<Base, Condition> = Pick<
40
42
  Base,
@@ -48,6 +48,8 @@ const mapEntries: Entries<typeof map> = [['a', 1]];
48
48
  const setExample = new Set(['a', 1]);
49
49
  const setEntries: Entries<typeof setExample> = [['a', 'a'], [1, 1]];
50
50
  ```
51
+
52
+ @category Utilities
51
53
  */
52
54
  export type Entries<BaseType> =
53
55
  BaseType extends Map<unknown, unknown> ? MapEntries<BaseType>
package/source/entry.d.ts CHANGED
@@ -51,6 +51,8 @@ const setExample = new Set(['a', 1]);
51
51
  const setEntryString: Entry<typeof setExample> = ['a', 'a'];
52
52
  const setEntryNumber: Entry<typeof setExample> = [1, 1];
53
53
  ```
54
+
55
+ @category Utilities
54
56
  */
55
57
  export type Entry<BaseType> =
56
58
  BaseType extends Map<unknown, unknown> ? MapEntry<BaseType>
@@ -18,5 +18,7 @@ type Foo = {
18
18
  type FooWithoutA = Except<Foo, 'a' | 'c'>;
19
19
  //=> {b: string};
20
20
  ```
21
+
22
+ @category Utilities
21
23
  */
22
24
  export type Except<ObjectType, KeysType extends keyof ObjectType> = Pick<ObjectType, Exclude<keyof ObjectType, KeysType>>;
@@ -27,6 +27,8 @@ const homeFencingTeam: FencingTeam = ['George', 'John'];
27
27
  guestFencingTeam.push('Sam');
28
28
  //=> error TS2339: Property 'push' does not exist on type 'FencingTeam'
29
29
  ```
30
+
31
+ @category Utilities
30
32
  */
31
33
  export type FixedLengthArray<Element, Length extends number, ArrayPrototype = [Element, ...Element[]]> = Pick<
32
34
  ArrayPrototype,
@@ -37,6 +37,8 @@ An example with an array of strings:
37
37
  ```
38
38
  type MeString = IterableElement<string[]>
39
39
  ```
40
+
41
+ @category Utilities
40
42
  */
41
43
  export type IterableElement<TargetIterable> =
42
44
  TargetIterable extends Iterable<infer ElementType> ?
@@ -26,6 +26,8 @@ type Pet2 = LiteralUnion<'dog' | 'cat', string>;
26
26
  const pet: Pet2 = '';
27
27
  // You **will** get auto-completion for `dog` and `cat` literals.
28
28
  ```
29
+
30
+ @category Utilities
29
31
  */
30
32
  export type LiteralUnion<
31
33
  LiteralType,
@@ -31,6 +31,8 @@ exclusiveOptions = {exclusive2: 'hi'};
31
31
  exclusiveOptions = {exclusive1: true, exclusive2: 'hi'};
32
32
  //=> Error
33
33
  ```
34
+
35
+ @category Utilities
34
36
  */
35
37
  export type MergeExclusive<FirstType, SecondType> =
36
38
  (FirstType | SecondType) extends object ?
package/source/merge.d.ts CHANGED
@@ -21,5 +21,7 @@ type Bar = {
21
21
 
22
22
  const ab: Merge<Foo, Bar> = {a: 1, b: 2};
23
23
  ```
24
+
25
+ @category Utilities
24
26
  */
25
27
  export type Merge<FirstType, SecondType> = Simplify<Merge_<FirstType, SecondType>>;
@@ -16,7 +16,7 @@ type Foo = {
16
16
  readonly c: boolean;
17
17
  };
18
18
 
19
- const mutableFoo: Mutable<Foo> = {a: 1, b: ['2']};
19
+ const mutableFoo: Mutable<Foo> = {a: 1, b: ['2'], c: true};
20
20
  mutableFoo.a = 3;
21
21
  mutableFoo.b[0] = 'new value'; // Will still fail as the value of property "b" is still a readonly type.
22
22
  mutableFoo.b = ['something']; // Will work as the "b" property itself is no longer readonly.
@@ -28,6 +28,8 @@ type SomeMutable = Mutable<Foo, 'b' | 'c'>;
28
28
  // c: boolean; // It's now mutable.
29
29
  // }
30
30
  ```
31
+
32
+ @category Utilities
31
33
  */
32
34
  export type Mutable<BaseType, Keys extends keyof BaseType = keyof BaseType> =
33
35
  Simplify<
@@ -6,6 +6,8 @@ declare global {
6
6
 
7
7
  /**
8
8
  Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable).
9
+
10
+ @category Basic
9
11
  */
10
12
  export interface ObservableLike {
11
13
  subscribe(observer: (value: unknown) => void): void;
@@ -61,5 +61,7 @@ type Person = {
61
61
  name: string;
62
62
  };
63
63
  ```
64
+
65
+ @category Utilities
64
66
  */
65
67
  export type Opaque<Type, Token = unknown> = Type & {readonly __opaque__: Token};
@@ -629,6 +629,8 @@ declare namespace PackageJson {
629
629
 
630
630
  /**
631
631
  Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Also includes types for fields used by other popular projects, like TypeScript and Yarn.
632
+
633
+ @category Miscellaneous
632
634
  */
633
635
  export type PackageJson =
634
636
  PackageJson.PackageJsonStandard &
@@ -27,6 +27,8 @@ const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {
27
27
 
28
28
  settings = applySavedSettings({textEditor: {fontWeight: 500}});
29
29
  ```
30
+
31
+ @category Utilities
30
32
  */
31
33
  export type PartialDeep<T> = T extends Primitive
32
34
  ? Partial<T>
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
3
+
4
+ @category Basic
3
5
  */
4
6
  export type Primitive =
5
7
  | null
@@ -18,6 +18,8 @@ async function logger(getLogEntry: () => Promisable<string>): Promise<void> {
18
18
 
19
19
  logger(() => 'foo');
20
20
  logger(() => Promise.resolve('bar'));
21
+
22
+ @category Utilities
21
23
  ```
22
24
  */
23
25
  export type Promisable<T> = T | PromiseLike<T>;
@@ -21,6 +21,8 @@ let syncData: SyncData = getSyncData();
21
21
  type RecursiveAsyncData = Promise<Promise<string> >;
22
22
  let recursiveAsyncData: PromiseValue<RecursiveAsyncData> = Promise.resolve(Promise.resolve('ABC'));
23
23
  ```
24
+
25
+ @category Utilities
24
26
  */
25
27
  export type PromiseValue<PromiseType, Otherwise = PromiseType> = PromiseType extends Promise<infer Value>
26
28
  ? { 0: PromiseValue<Value>; 1: Value }[PromiseType extends Promise<unknown> ? 0 : 1]
@@ -28,6 +28,8 @@ import data from './main';
28
28
  data.foo.push('bar');
29
29
  //=> error TS2339: Property 'push' does not exist on type 'readonly string[]'
30
30
  ```
31
+
32
+ @category Utilities
31
33
  */
32
34
  export type ReadonlyDeep<T> = T extends Primitive | ((...arguments: any[]) => unknown)
33
35
  ? T
@@ -19,6 +19,8 @@ const responder: RequireAtLeastOne<Responder, 'text' | 'json'> = {
19
19
  secure: true
20
20
  };
21
21
  ```
22
+
23
+ @category Utilities
22
24
  */
23
25
  export type RequireAtLeastOne<
24
26
  ObjectType,
@@ -27,6 +27,8 @@ const responder: RequireExactlyOne<Responder, 'text' | 'json'> = {
27
27
  secure: true
28
28
  };
29
29
  ```
30
+
31
+ @category Utilities
30
32
  */
31
33
  export type RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
32
34
  {[Key in KeysType]: (
@@ -23,6 +23,8 @@ type SomeOptional = SetOptional<Foo, 'b' | 'c'>;
23
23
  // c?: boolean; // Is now optional.
24
24
  // }
25
25
  ```
26
+
27
+ @category Utilities
26
28
  */
27
29
  export type SetOptional<BaseType, Keys extends keyof BaseType> =
28
30
  Simplify<
@@ -23,6 +23,8 @@ type SomeRequired = SetRequired<Foo, 'b' | 'c'>;
23
23
  // c: boolean; // Is now required.
24
24
  // }
25
25
  ```
26
+
27
+ @category Utilities
26
28
  */
27
29
  export type SetRequired<BaseType, Keys extends keyof BaseType> =
28
30
  Simplify<
@@ -16,6 +16,8 @@ type MyFunctionThatCanThrow = (foo: SomeType, bar: unknown) => SomeOtherType;
16
16
  type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | undefined>;
17
17
  //=> type MyWrappedFunction = (foo: SomeType, bar: unknown) => SomeOtherType | undefined;
18
18
  ```
19
+
20
+ @category Utilities
19
21
  */
20
22
  export type SetReturnType<Fn extends (...args: any[]) => any, TypeToReturn> =
21
23
  // Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter.
@@ -17,5 +17,7 @@ const carForm: Stringified<Car> = {
17
17
  speed: '101'
18
18
  };
19
19
  ```
20
+
21
+ @category Utilities
20
22
  */
21
23
  export type Stringified<ObjectType> = {[KeyType in keyof ObjectType]: string};
@@ -815,6 +815,11 @@ declare namespace TsConfigJson {
815
815
  }
816
816
  }
817
817
 
818
+ /**
819
+ Type for [TypeScript's `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) (TypeScript 3.7).
820
+
821
+ @category Miscellaneous
822
+ */
818
823
  export interface TsConfigJson {
819
824
  /**
820
825
  Instructs the TypeScript compiler how to compile `.ts` files.
@@ -2,6 +2,8 @@
2
2
 
3
3
  /**
4
4
  Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`.
5
+
6
+ @category Basic
5
7
  */
6
8
  export type TypedArray =
7
9
  | Int8Array
@@ -40,6 +40,8 @@ type Union = typeof union;
40
40
  type Intersection = UnionToIntersection<Union>;
41
41
  //=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
42
42
  ```
43
+
44
+ @category Utilities
43
45
  */
44
46
  export type UnionToIntersection<Union> = (
45
47
  // `extends unknown` is always going to be the case and is used to convert the
@@ -36,5 +36,7 @@ onlyBar('foo');
36
36
  onlyBar('bar');
37
37
  //=> 2
38
38
  ```
39
+
40
+ @category Utilities
39
41
  */
40
42
  export type ValueOf<ObjectType, ValueType extends keyof ObjectType = keyof ObjectType> = ObjectType[ValueType];
@@ -60,5 +60,7 @@ const dbResult: CamelCasedProperties<ModelProps> = {
60
60
  foo: 123
61
61
  };
62
62
  ```
63
+
64
+ @category Template Literals
63
65
  */
64
- export type CamelCase<K> = K extends string ? CamelCaseStringArray<Split<K, WordSeparators>> : K;
66
+ export type CamelCase<K> = K extends string ? K extends Uppercase<K> ? Lowercase<K> : CamelCaseStringArray<Split<K, WordSeparators>> : K;
@@ -37,6 +37,8 @@ const result: CamelCasedPropertiesDeep<UserWithFriends> = {
37
37
  ],
38
38
  };
39
39
  ```
40
+
41
+ @category Template Literals
40
42
  */
41
43
  export type CamelCasedPropertiesDeep<Value> = Value extends Function
42
44
  ? Value
@@ -20,6 +20,8 @@ const result: CamelCasedProperties<User> = {
20
20
  userName: 'Tom',
21
21
  };
22
22
  ```
23
+
24
+ @category Template Literals
23
25
  */
24
26
  export type CamelCasedProperties<Value> = Value extends Function
25
27
  ? Value
@@ -2,6 +2,8 @@ import {UpperCaseCharacters, WordSeparators} from '../source/utilities';
2
2
 
3
3
  /**
4
4
  Unlike a simpler split, this one includes the delimiter splitted on in the resulting array literal. This is to enable splitting on, for example, upper-case characters.
5
+
6
+ @category Template Literals
5
7
  */
6
8
  export type SplitIncludingDelimiters<Source extends string, Delimiter extends string> =
7
9
  Source extends '' ? [] :
@@ -73,8 +75,9 @@ const rawCliOptions: OddlyCasedProperties<SomeOptions> = {
73
75
  foo: 123
74
76
  };
75
77
  ```
76
- */
77
78
 
79
+ @category Template Literals
80
+ */
78
81
  export type DelimiterCase<Value, Delimiter extends string> = Value extends string
79
82
  ? StringArrayToDelimiterCase<
80
83
  SplitIncludingDelimiters<Value, WordSeparators | UpperCaseCharacters>,
@@ -37,6 +37,8 @@ const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = {
37
37
  ],
38
38
  };
39
39
  ```
40
+
41
+ @category Template Literals
40
42
  */
41
43
  export type DelimiterCasedPropertiesDeep<
42
44
  Value,
@@ -20,6 +20,8 @@ const result: DelimiterCasedProperties<User, '-'> = {
20
20
  'user-name': 'Tom',
21
21
  };
22
22
  ```
23
+
24
+ @category Template Literals
23
25
  */
24
26
  export type DelimiterCasedProperties<
25
27
  Value,
package/ts41/get.d.ts CHANGED
@@ -127,5 +127,7 @@ const getName = (apiResponse: ApiResponse) =>
127
127
  get(apiResponse, 'hits.hits[0]._source.name');
128
128
  //=> Array<{given: string[]; family: string}>
129
129
  ```
130
+
131
+ @category Template Literals
130
132
  */
131
133
  export type Get<BaseType, Path extends string> = GetWithPath<BaseType, ToPath<Path>>;
package/ts41/index.d.ts CHANGED
@@ -14,6 +14,7 @@ export {PascalCasedPropertiesDeep} from './pascal-cased-properties-deep';
14
14
  export {SnakeCase} from './snake-case';
15
15
  export {SnakeCasedProperties} from './snake-cased-properties';
16
16
  export {SnakeCasedPropertiesDeep} from './snake-cased-properties-deep';
17
+ export {ScreamingSnakeCase} from './screaming-snake-case';
17
18
  export {DelimiterCase} from './delimiter-case';
18
19
  export {DelimiterCasedProperties} from './delimiter-cased-properties';
19
20
  export {DelimiterCasedPropertiesDeep} from './delimiter-cased-properties-deep';
@@ -31,6 +31,7 @@ const rawCliOptions: KebabCasedProperties<CliOptions> = {
31
31
  foo: 123
32
32
  };
33
33
  ```
34
- */
35
34
 
35
+ @category Template Literals
36
+ */
36
37
  export type KebabCase<Value> = DelimiterCase<Value, '-'>;
@@ -37,5 +37,7 @@ const result: KebabCasedPropertiesDeep<UserWithFriends> = {
37
37
  ],
38
38
  };
39
39
  ```
40
+
41
+ @category Template Literals
40
42
  */
41
43
  export type KebabCasedPropertiesDeep<Value> = DelimiterCasedPropertiesDeep<Value, '-'>;
@@ -20,5 +20,7 @@ const result: KebabCasedProperties<User> = {
20
20
  'user-name': 'Tom',
21
21
  };
22
22
  ```
23
+
24
+ @category Template Literals
23
25
  */
24
26
  export type KebabCasedProperties<Value> = DelimiterCasedProperties<Value, '-'>;
@@ -14,6 +14,8 @@ const array = ['foo', 2];
14
14
  typeof lastOf(array);
15
15
  //=> number
16
16
  ```
17
+
18
+ @category Template Literals
17
19
  */
18
20
  export type LastArrayElement<ValueType extends unknown[]> =
19
21
  ValueType extends [infer ElementType]
@@ -29,8 +29,9 @@ const dbResult: CamelCasedProperties<ModelProps> = {
29
29
  Foo: 123
30
30
  };
31
31
  ```
32
- */
33
32
 
33
+ @category Template Literals
34
+ */
34
35
  export type PascalCase<Value> = CamelCase<Value> extends string
35
36
  ? Capitalize<CamelCase<Value>>
36
37
  : CamelCase<Value>;
@@ -37,6 +37,8 @@ const result: PascalCasedPropertiesDeep<UserWithFriends> = {
37
37
  ],
38
38
  };
39
39
  ```
40
+
41
+ @category Template Literals
40
42
  */
41
43
  export type PascalCasedPropertiesDeep<Value> = Value extends Function
42
44
  ? Value
@@ -20,6 +20,8 @@ const result: PascalCasedProperties<User> = {
20
20
  UserName: 'Tom',
21
21
  };
22
22
  ```
23
+
24
+ @category Template Literals
23
25
  */
24
26
  export type PascalCasedProperties<Value> = Value extends Function
25
27
  ? Value
@@ -0,0 +1,40 @@
1
+ import {SplitIncludingDelimiters} from './delimiter-case';
2
+ import {SnakeCase} from './snake-case';
3
+
4
+ /**
5
+ Returns a boolean for whether the given array includes the given item.
6
+ */
7
+ type Includes<Value extends any[], Item> = {
8
+ [P in keyof Value & number as Value[P]]: true;
9
+ }[Item] extends true
10
+ ? true
11
+ : false;
12
+
13
+ /**
14
+ Returns a boolean for whether the string is screaming snake case.
15
+ */
16
+ type IsScreamingSnakeCase<Value extends string> = Value extends Uppercase<Value>
17
+ ? Includes<SplitIncludingDelimiters<Lowercase<Value>, '_'>, '_'> extends true
18
+ ? true
19
+ : false
20
+ : false;
21
+
22
+ /**
23
+ Convert a string literal to screaming-snake-case.
24
+
25
+ This can be useful when, for example, converting a camel-cased object property to a screaming-snake-cased SQL column name.
26
+
27
+ @example
28
+ ```
29
+ import {ScreamingSnakeCase} from 'type-fest';
30
+
31
+ const someVariable: ScreamingSnakeCase<'fooBar'> = 'FOO_BAR';
32
+ ```
33
+
34
+ @category Template Literals
35
+ */
36
+ export type ScreamingSnakeCase<Value> = Value extends string
37
+ ? IsScreamingSnakeCase<Value> extends true
38
+ ? Value
39
+ : Uppercase<SnakeCase<Value>>
40
+ : Value;
@@ -31,5 +31,7 @@ const dbResult: SnakeCasedProperties<ModelProps> = {
31
31
  foo: 123
32
32
  };
33
33
  ```
34
+
35
+ @category Template Literals
34
36
  */
35
37
  export type SnakeCase<Value> = DelimiterCase<Value, '_'>;
@@ -37,5 +37,7 @@ const result: SnakeCasedPropertiesDeep<UserWithFriends> = {
37
37
  ],
38
38
  };
39
39
  ```
40
+
41
+ @category Template Literals
40
42
  */
41
43
  export type SnakeCasedPropertiesDeep<Value> = DelimiterCasedPropertiesDeep<Value, '_'>;
@@ -20,5 +20,7 @@ const result: SnakeCasedProperties<User> = {
20
20
  user_name: 'Tom',
21
21
  };
22
22
  ```
23
+
24
+ @category Template Literals
23
25
  */
24
26
  export type SnakeCasedProperties<Value> = DelimiterCasedProperties<Value, '_'>;
package/ts41/split.d.ts CHANGED
@@ -15,8 +15,14 @@ let array: Item[];
15
15
 
16
16
  array = split(items, ',');
17
17
  ```
18
+
19
+ @category Template Literals
18
20
  */
19
- export type Split<S extends string, D extends string> =
20
- S extends `${infer T}${D}${infer U}`
21
- ? [T, ...Split<U, D>]
22
- : [S];
21
+ export type Split<
22
+ S extends string,
23
+ Delimiter extends string
24
+ > = S extends `${infer Head}${Delimiter}${infer Tail}`
25
+ ? [Head, ...Split<Tail, Delimiter>]
26
+ : S extends Delimiter
27
+ ? []
28
+ : [S];
package/ts41/trim.d.ts CHANGED
@@ -18,5 +18,7 @@ import {Trim} from 'type-fest';
18
18
  Trim<' foo '>
19
19
  //=> 'foo'
20
20
  ```
21
+
22
+ @category Template Literals
21
23
  */
22
24
  export type Trim<V extends string> = TrimLeft<TrimRight<V>>;