Jelajahi Sumber

feat: ListWithLength type and support ListWithLength in autoPlural()

Sv443 2 bulan lalu
induk
melakukan
eb20132
6 mengubah file dengan 67 tambahan dan 8 penghapusan
  1. 5 0
      .changeset/fifty-tigers-live.md
  2. 5 0
      .changeset/gorgeous-scissors-sparkle.md
  3. 1 0
      README-summary.md
  4. 1 0
      README.md
  5. 40 4
      docs.md
  6. 15 4
      lib/misc.ts

+ 5 - 0
.changeset/fifty-tigers-live.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": minor
+---
+
+Added the type `ListWithLength` to represent an array or object with a numeric `length`, `count` or `size` property.

+ 5 - 0
.changeset/gorgeous-scissors-sparkle.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": minor
+---
+
+Added `autoPlural()` support for generic objects with a numeric `length`, `count` or `size` property.

+ 1 - 0
README-summary.md

@@ -95,6 +95,7 @@ View the documentation of previous major releases:
     - [`Prettify`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#prettify) - expands a complex type into a more readable format while keeping functionality the same
     - [`ValueGen`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#valuegen) - a "generator" value that allows for super flexible value typing and declaration
     - [`StringGen`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#stringgen) - a "generator" string that allows for super flexible string typing and declaration, including enhanced support for unions
+    - [`ListWithLength`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#listwithlength) - represents an array or object with a numeric `length`, `count` or `size` property
 
 <br><br>
 

+ 1 - 0
README.md

@@ -102,6 +102,7 @@ View the documentation of previous major releases:
     - [`Prettify`](./docs.md#prettify) - expands a complex type into a more readable format while keeping functionality the same
     - [`ValueGen`](./docs.md#valuegen) - a "generator" value that allows for super flexible value typing and declaration
     - [`StringGen`](./docs.md#stringgen) - a "generator" string that allows for super flexible string typing and declaration, including enhanced support for unions
+    - [`ListWithLength`](./docs.md#listwithlength) - represents an array or object with a numeric `length`, `count` or `size` property
 
 <br><br>
 

+ 40 - 4
docs.md

@@ -91,6 +91,7 @@ For submitting bug reports or feature requests, please use the [GitHub issue tra
     - [`Prettify`](#prettify) - expands a complex type into a more readable format while keeping functionality the same
     - [`ValueGen`](#valuegen) - a "generator" value that allows for super flexible value typing and declaration
     - [`StringGen`](#stringgen) - a "generator" string that allows for super flexible string typing and declaration, including enhanced support for unions
+    - [`ListWithLength`](#listwithlength) - represents an array or object with a numeric `length`, `count` or `size` property
 
 <br><br>
 
@@ -1930,13 +1931,14 @@ debouncedFunction.debouncer.on("change", (timeout, type) => {
 ### autoPlural()
 Signature:  
 ```ts
-autoPlural(str: string, num: number | Array | NodeList): string
+autoPlural(str: string, num: number | Array | NodeList | { length: number } | { count: number } | { size: number }): string
 ```
   
 Crudely pluralizes a string by appending an `s` if the given number is not 1.  
-If an array or NodeList is passed, the amount of contained items will be used.  
-
-Of course some English words go from `-y` to `-ies`, in which case this function will not work.  
+If an array or NodeList or object with either a `length`, `count` or `size` property is passed, the amount of contained items will be used.  
+Iterables will not work until converted to an array (with `Array.from()` or `[...iterable]`).  
+  
+Some English words go from `-y` to `-ies`. Using this function in that case will not work.  
   
 <details><summary><b>Example - click to view</b></summary>
 
@@ -3150,6 +3152,40 @@ Remember that [`Stringifiable`](#stringifiable) is a type that describes a value
 Contrary to [`ValueGen`](#valuegen), this type allows for specifying a union of strings that the StringGen should yield, as long as it is loosely typed as just `string`.  
 Use it in the [`consumeStringGen()`](#consumestringgen) function to convert the given StringGen value to a plain string. Also refer to that function for an example.
 
+<br>
+
+### ListWithLength
+Represents a value that is either an array, NodeList, or any other object that has a numeric `length`, `count` or `size` property.  
+Iterables are not included because they don't have a length property. They need to be converted to an array first using `Array.from()` or `[...iterable]`.  
+
+<details><summary><b>Example - click to view</b></summary>
+
+```ts
+import type { ListWithLength } from "@sv443-network/userutils";
+
+function getSize(list: ListWithLength) {
+  let size = -1;
+  if("length" in list)
+    size = list.length;
+  else if("count" in list)
+    size = list.count;
+  else if("size" in list)
+    size = list.size;
+
+  return size;
+}
+
+getSize([1, 2, 3]); // 3
+getSize(document.querySelectorAll("div")); // 5
+getSize(new Map([["a", 1], ["b", 2]])); // 2
+getSize({ count: 42 }); // 42
+
+// iterables need to be converted:
+const iter = new Map([["a", 1]]).entries();
+getSize([...iter]); // 1
+```
+</details>
+
 <br><br><br><br>
 
 <!-- #region Footer -->

+ 15 - 4
lib/misc.ts

@@ -5,14 +5,25 @@
 
 import type { Prettify, Stringifiable } from "./types.js";
 
+/** Any value that is list-like, i.e. has a numeric length, count or size property */
+export type ListWithLength = unknown[] | NodeList | { length: number } | { count: number } | { size: number };
+
 /**
  * Automatically appends an `s` to the passed {@linkcode word}, if {@linkcode num} is not equal to 1
  * @param word A word in singular form, to auto-convert to plural
- * @param num If this is an array or NodeList, the amount of items is used
+ * @param num A number, or list-like value that has either a `length`, `count` or `size` property - does not support iterables
  */
-export function autoPlural(word: Stringifiable, num: number | unknown[] | NodeList): string {
-  if(Array.isArray(num) || num instanceof NodeList)
-    num = num.length;
+export function autoPlural(word: Stringifiable, num: number | ListWithLength): string {
+  if(typeof num !== "number") {
+    if(Array.isArray(num) || num instanceof NodeList)
+      num = num.length;
+    else if("length" in num)
+      num = num.length;
+    else if("count" in num)
+      num = num.count;
+    else if("size" in num)
+      num = num.size;
+  }
   return `${word}${num === 1 ? "" : "s"}`;
 }