@infra-blocks/types 0.33.0 → 0.34.0-alpha.0

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.
@@ -31,6 +31,28 @@ export type Brand<T extends PropertyKey = PropertyKey> = {
31
31
  * A type alias for {@link NotUndefined}, because double negation sucks azz.
32
32
  */
33
33
  export type Defined<T> = Exclude<T, undefined>;
34
+ /**
35
+ * A type alias for an empty object.
36
+ *
37
+ * Usage of '{}' as a type is frowned upon by linters, as it is misleading.
38
+ * It actually means any 'non nullish value'.
39
+ *
40
+ * However, modeling empty objects can be incredibly useful while building
41
+ * conditional types, and particularly while building intersection types.
42
+ * This is true since the empty object is neutral in an intersection:
43
+ * `{ toto: string } & {} = { toto: string }`.
44
+ *
45
+ * This is where this type comes in. It replaces the empty object for those
46
+ * purposes.
47
+ *
48
+ * @example
49
+ * // Linters don't like this.
50
+ * type BadResult<T> = (T extends string ? { isString: true } : {}) & (T extends number ? { isNumber: true} : {});
51
+ * // Linters love this shit.
52
+ * import { Empty } from "@infra-blocks/types";
53
+ * type GoodResult<T> = (T extends string ? { isString: true } : Empty) & (T extends number ? { isNumber: true} : Empty);
54
+ */
55
+ export type EmptyObject = Record<never, never>;
34
56
  /**
35
57
  * Convenience type to represent environment variables.
36
58
  */
@@ -31,6 +31,28 @@ export type Brand<T extends PropertyKey = PropertyKey> = {
31
31
  * A type alias for {@link NotUndefined}, because double negation sucks azz.
32
32
  */
33
33
  export type Defined<T> = Exclude<T, undefined>;
34
+ /**
35
+ * A type alias for an empty object.
36
+ *
37
+ * Usage of '{}' as a type is frowned upon by linters, as it is misleading.
38
+ * It actually means any 'non nullish value'.
39
+ *
40
+ * However, modeling empty objects can be incredibly useful while building
41
+ * conditional types, and particularly while building intersection types.
42
+ * This is true since the empty object is neutral in an intersection:
43
+ * `{ toto: string } & {} = { toto: string }`.
44
+ *
45
+ * This is where this type comes in. It replaces the empty object for those
46
+ * purposes.
47
+ *
48
+ * @example
49
+ * // Linters don't like this.
50
+ * type BadResult<T> = (T extends string ? { isString: true } : {}) & (T extends number ? { isNumber: true} : {});
51
+ * // Linters love this shit.
52
+ * import { Empty } from "@infra-blocks/types";
53
+ * type GoodResult<T> = (T extends string ? { isString: true } : Empty) & (T extends number ? { isNumber: true} : Empty);
54
+ */
55
+ export type EmptyObject = Record<never, never>;
34
56
  /**
35
57
  * Convenience type to represent environment variables.
36
58
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infra-blocks/types",
3
- "version": "0.33.0",
3
+ "version": "0.34.0-alpha.0",
4
4
  "description": "Typescript types utility package.",
5
5
  "keywords": [
6
6
  "type",