export function canBeCastAsPositiveIntegerOrNull( probablePositiveNumberOrNull: string | undefined | number | null, ): probablePositiveNumberOrNull is number | null { if (probablePositiveNumberOrNull === undefined) { return false; } if (typeof probablePositiveNumberOrNull === 'number') { return ( Number.isInteger(probablePositiveNumberOrNull) && Math.sign(probablePositiveNumberOrNull) !== -1 ); } if (probablePositiveNumberOrNull === null) { return true; } if (probablePositiveNumberOrNull === '') { return true; } if (typeof probablePositiveNumberOrNull === 'string') { const stringAsNumber = +probablePositiveNumberOrNull; if (isNaN(stringAsNumber)) { return false; } if (Number.isInteger(stringAsNumber) && Math.sign(stringAsNumber) !== -1) { return true; } } return false; } export function castAsPositiveIntegerOrNull( probablePositiveNumberOrNull: string | undefined | number | null, ): number | null { if ( canBeCastAsPositiveIntegerOrNull(probablePositiveNumberOrNull) === false ) { throw new Error('Cannot cast to positive number or null'); } if (probablePositiveNumberOrNull === null) { return null; } if (probablePositiveNumberOrNull === '') { return null; } if (typeof probablePositiveNumberOrNull === 'number') { return probablePositiveNumberOrNull; } if (typeof probablePositiveNumberOrNull === 'string') { return +probablePositiveNumberOrNull; } return null; }