nextjs-demo
next.js demo using react 19 rc
git clone https://9o.is/git/nextjs-demo.git
objects.ts
(1812B)
1 type KeysOfType<T, U> = {
2 [K in keyof T]: T[K] extends U ? K : never
3 }[keyof T]
4
5 type NumberKeysOf<T> = KeysOfType<T, number>
6
7 export const SORT_TYPES = ["ascending", "descending"] as const
8 export type SortType = typeof SORT_TYPES[number]
9
10 export function isSortType(value: string | undefined | null): value is SortType {
11 return value === "ascending" || value === "descending"
12 }
13
14 export function isPromise<T>(value: unknown): value is Promise<T> {
15 return value instanceof Promise
16 }
17
18 export function asArray<T>(value: T | T[] | undefined | null): T[] {
19 return Array.isArray(value) ? value :
20 value !== undefined && value !== null ? [value] : []
21 }
22
23 export function filterByProp<T extends object>(prop: keyof T, value: T[keyof T], objects: T[]): T[] {
24 return objects.filter(object => object[prop] === value)
25 }
26
27 export function sortByProp<T,>(prop: NumberKeysOf<T>, order: SortType, objects: T[]): T[] {
28 return [...objects].sort((a: T, b: T) => {
29 if (!order || typeof a[prop] !== "number" || typeof b[prop] !== "number") return 0
30 if (order === "ascending") return a[prop] - b[prop]
31 return b[prop] - a[prop]
32 })
33 }
34
35 export function minByProp<T extends object>(prop: NumberKeysOf<T>, objects: T[]): T | null {
36 if (objects.length === 0) return null
37 if (objects.length === 1) return objects[0]
38
39 const [fst, snd, ...tail] = objects
40 const min = fst[prop] < snd[prop] ? fst : snd
41 return minByProp(prop, [min, ...tail])
42 }
43
44 // Alternative implementation using reduce
45 // const minByProp = <T extends object>(prop: NumberKeysOf<T>, objects: T[]): T | undefined => {
46 // if (objects.length === 0) return undefined
47
48 // return objects.reduce((minObj, currentObj) => {
49 // return currentObj[prop] < minObj[prop] ? currentObj : minObj
50 // })
51 // }