ts: add types to common helpers

This commit is contained in:
axolotle 2024-07-22 17:51:53 +02:00
parent 83e09d6ae9
commit 016acc7b50

View file

@ -1,13 +1,19 @@
import type { UnwrapRef } from 'vue'
import type { Obj } from '@/types/commons'
/**
* Allow to set a timeout on a `Promise` expected response.
* The returned Promise will be rejected if the original Promise is not resolved or
* rejected before the delay.
*
* @param {Promise} promise - A promise (like a fetch call).
* @param {Number} delay - delay after which the promise is rejected
* @return {Promise}
* @param promise - A promise (like a fetch call).
* @param delay - delay after which the promise is rejected
*/
export function timeout(promise, delay) {
export function timeout<T extends unknown>(
promise: Promise<T>,
delay: number,
): Promise<T> {
return new Promise((resolve, reject) => {
// FIXME reject(new Error('api_not_responding')) for post-install
setTimeout(() => reject, delay)
@ -18,10 +24,9 @@ export function timeout(promise, delay) {
/**
* Check if passed value is an object literal.
*
* @param {*} value - Anything.
* @return {Boolean}
* @param value - Anything.
*/
export function isObjectLiteral(value) {
export function isObjectLiteral(value: any): value is object {
return (
value !== null &&
value !== undefined &&
@ -41,23 +46,52 @@ export function objectGet<
* Check if value is "empty" (`null`, `undefined`, `''`, `[]`, '{}').
* Note: `0` is not considered "empty" in that helper.
*
* @param {*} value - Anything.
* @return {Boolean}
* @param value - Anything.
*/
export function isEmptyValue(value) {
if (typeof value === 'number') return false
return !value || value.length === 0 || Object.keys(value).length === 0
export function isEmptyValue(
value: any,
): value is null | undefined | '' | [] | {} {
if (typeof value === 'number' || typeof value === 'boolean') return false
return (
!value ||
(Array.isArray(value) && value.length === 0) ||
Object.keys(value).length === 0
)
}
type Flatten<T extends object> = object extends T
? object
: {
[K in keyof T]-?: (
x: NonNullable<T[K]> extends infer V
? V extends object
? V extends readonly any[]
? Pick<T, K>
: Flatten<V> extends infer FV
? {
[P in keyof FV as `${Extract<P, string | number>}`]: FV[P]
}
: never
: Pick<T, K>
: never,
) => void
} extends Record<keyof T, (y: infer O) => void>
? O extends infer U
? { [K in keyof O]: O[K] }
: never
: never
/**
* Returns an flattened object literal, with all keys at first level and removing nested ones.
*
* @param {Object} obj - An object literal to flatten.
* @param {Object} [flattened={}] - An object literal to add passed obj keys/values.
* @return {Object}
* @param obj - An object literal to flatten.
* @param flattened - An object literal to add passed obj keys/values.
*/
export function flattenObjectLiteral(obj, flattened = {}) {
function flatten(objLit) {
export function flattenObjectLiteral<T extends object>(
obj: T,
flattened: Partial<Flatten<T>> = {},
) {
function flatten(objLit: Partial<Flatten<T>>) {
for (const key in objLit) {
const value = objLit[key]
if (isObjectLiteral(value)) {
@ -68,18 +102,24 @@ export function flattenObjectLiteral(obj, flattened = {}) {
}
}
flatten(obj)
return flattened
return flattened as Flatten<T>
}
/**
* Returns an new Object filtered with passed filter function.
* Each entry `[key, value]` will be forwarded to the `filter` function.
*
* @param {Object} obj - object to filter.
* @param {Function} filter - the filter function to call for each entry.
* @return {Object}
* @param obj - object to filter.
* @param filter - the filter function to call for each entry.
*/
export function filterObject(obj, filter) {
export function filterObject<T extends Obj>(
obj: T,
filter: (
entries: [string, any],
index: number,
array: [string, any][],
) => boolean,
) {
return Object.fromEntries(
Object.entries(obj).filter((...args) => filter(...args)),
)
@ -87,22 +127,20 @@ export function filterObject(obj, filter) {
/**
* Returns an new array containing items that are in first array but not in the other.
*
* @param {Array} [arr1=[]]
* @param {Array} [arr2=[]]
* @return {Array}
*/
export function arrayDiff(arr1 = [], arr2 = []) {
export function arrayDiff<T extends string>(
arr1: T[] = [],
arr2: T[] = [],
): T[] {
return arr1.filter((item) => !arr2.includes(item))
}
/**
* Returns a new string with escaped HTML (`&<>"'` replaced by entities).
*
* @param {String} unsafe
* @return {String}
* @param unsafe - string to escape
*/
export function escapeHtml(unsafe) {
export function escapeHtml(unsafe: string) {
return unsafe
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
@ -114,11 +152,10 @@ export function escapeHtml(unsafe) {
/**
* Returns a random integer between `min` and `max`.
*
* @param {Number} min
* @param {Number} max
* @return {Number}
* @param min - min possible value
* @param max - max possible value
*/
export function randint(min, max) {
export function randint(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min
}