datum-focus
Version:
Data shape, model, metadata, JSON, JSON Schema, GraphQL, MongoDB query and aggregations, iterator generators
139 lines (109 loc) • 3.99 kB
text/typescript
// <reference types="../../typings/number" />
// <reference types="../../typings/string" />
// used for counting
export type CardinalNumber = PositiveInteger;
export type Count = NonNegativeInteger;
export type FibonacciNumber = PositiveInteger;
export type Integer = number;
export type NaN = number;
export type NaturalNumber = CardinalNumber;
export type NegativeInteger = NonPositiveInteger;
export type NegativeNumber = NonPositiveNumber;
export type NonNegativeInteger = Integer;
export type NonNegativeNumber = Number;
export type NonPositiveInteger = Integer;
export type NonPositiveNumber = Number;
export type NumberOrString = number | string;
// used for ordering
export type OrdinalNumber = NonNegativeInteger;
export type PerfectSquare = PositiveInteger;
export type Pi = 3.14159265358979323846;
export type PositiveInteger = NonNegativeInteger;
export type PositiveNumber = NonNegativeNumber;
export type PrimeNumber = PositiveInteger;
import { isString } from "./string";
export const DECIMAL = "decimal";
export const DOUBLE = "double";
export const INTEGER = "integer";
export const ONE = 1;
export const NUMBER = "number";
export const TIMESTAMP = "timestamp";
export const ZERO = 0;
export const INTEGER_TYPES = [
INTEGER,
TIMESTAMP,
] as const;
export type IntegerType = typeof INTEGER_TYPES[number];
export const FLOAT_TYPES = [
DECIMAL,
DOUBLE,
NUMBER,
] as const;
export type FloatType = typeof FLOAT_TYPES[number];
export const NUMBER_TYPES = [
...INTEGER_TYPES,
...FLOAT_TYPES
] as const;
export type NumberType = typeof NUMBER_TYPES[number];
export const isInteger = (val: unknown): val is Integer =>
Number.isInteger(val);
export const isNaN = (val: unknown): val is NaN => Number.isNaN(val);
export const isNegativeInteger = (val: unknown): val is NegativeInteger =>
isInteger(val) && val < ZERO;
export const isNegativeNumber = (val: unknown): val is NegativeNumber =>
isNumber(val) && val < ZERO;
export const isNonNegativeInteger = (val: unknown): val is NonNegativeInteger =>
isInteger(val) && val <= ZERO;
export const isNonNegativeNumber = (val: unknown): val is NonNegativeNumber =>
isNumber(val) && val <= ZERO;
export const isNonPositiveInteger = (val: unknown): val is NonPositiveInteger =>
isInteger(val) && val <= ZERO;
export const isNonPositiveNumber = (val: unknown): val is NonPositiveNumber =>
isNumber(val) && val <= ZERO;
export const isNumber = (val: unknown): val is number =>
typeof val === NUMBER && val === val;
// A utility function that returns true if x is perfect square
export const isPerfectSquare = (val: unknown): val is PerfectSquare => {
if (!isPositiveInteger(val)) {
return false;
}
const sqrt = Math.sqrt(val);
return sqrt * sqrt === val;
};
// Returns true if n is a Fibinacci Number, else false
export const isFibonacci = (val: unknown): val is FibonacciNumber => {
if (!isPositiveInteger(val)) {
return false;
}
// n is Fibinacci if one of 5*n*n + 4 or 5*n*n - 4 or both
// is a perferct square
return (
isPerfectSquare(5 * val * val + 4) || isPerfectSquare(5 * val * val - 4)
);
};
export const isPositiveInteger = (val: unknown): val is PositiveInteger =>
isInteger(val) && val > ZERO;
export const isPositiveNumber = (val: unknown): val is PositiveNumber =>
isNumber(val) && val > ZERO;
export const isPrime = (val: unknown): val is PrimeNumber => {
if (!isPositiveInteger(val)) {
return false;
}
if (val === 2 || val === 3) {
return true;
} else if (val <= 1 || val % 2 === 0 || val % 3 === 0) {
return false;
}
let i = 5;
while (Math.pow(i, 2) <= val) {
if (val % i === 0 || val % (i + 2) === 0) {
return false;
}
i += 6;
}
return true;
};
export const isLeapYear = (val: unknown): val is number =>
isPositiveInteger(val) && new Date(val, 1, 29).getMonth() === 1;
export const isNumberOrString = (val: unknown): val is NumberOrString =>
isNumber(val) || isString(val);