Skip to content

Commit e1ff9e6

Browse files
authored
feat: add positive zero guards, constants, and types (#9)
* feat(guards): add @nick/math/guards/positive-zero * feat(constants): add @nick/constants/positive-zero * chore: update ./constants root entrypoint * refactor(guards): add positive-zero export to ./guards/mod.ts, improve docs * config: update deno.json exports * chore: pin dev deps and update scripts in deno.json * config: update publish config and other stuff in deno.json * chore: bump version
1 parent dcda20d commit e1ff9e6

File tree

5 files changed

+98
-17
lines changed

5 files changed

+98
-17
lines changed

deno.json

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"name": "@nick/math",
3-
"version": "0.4.2",
3+
"version": "0.5.0",
44
"license": "MIT",
55
"author": {
66
"name": "Nicholas Berlette",
77
"email": "[email protected]",
8-
"url": "https://github.com/nberlette"
8+
"url": "https://github.com/nberlette/math"
99
},
1010
"exports": {
1111
".": "./mod.ts",
@@ -66,6 +66,7 @@
6666
"./constants/negative-infinity": "./src/constants/negative_infinity.ts",
6767
"./constants/pi": "./src/constants/pi.ts",
6868
"./constants/positive-infinity": "./src/constants/positive_infinity.ts",
69+
"./constants/positive-zero": "./src/constants/positive_zero.ts",
6970
"./constants/sqrt1-2": "./src/constants/sqrt1_2.ts",
7071
"./constants/sqrt2": "./src/constants/sqrt2.ts",
7172
"./float16": "./src/float16/mod.ts",
@@ -82,6 +83,7 @@
8283
"./guards/positive-infinity": "./src/guards/positive_infinity.ts",
8384
"./guards/negative-infinity": "./src/guards/negative_infinity.ts",
8485
"./guards/negative-zero": "./src/guards/negative_zero.ts",
86+
"./guards/positive-zero": "./src/guards/positive_zero.ts",
8587
"./guards/integer": "./src/guards/integer.ts",
8688
"./guards/safe-integer": "./src/guards/safe_integer.ts",
8789
"./guards/nan": "./src/guards/nan.ts",
@@ -101,29 +103,28 @@
101103
"./types/safe-integer": "./src/types/safe_integer.ts"
102104
},
103105
"imports": {
104-
"@std/assert": "jsr:@std/assert@^1.0.11",
105-
"@std/testing": "jsr:@std/testing@^1.0.9",
106-
"@std/expect": "jsr:@std/expect@^1.0.13"
106+
"@std/assert": "jsr:@std/[email protected]",
107+
"@std/testing": "jsr:@std/[email protected]",
108+
"@std/expect": "jsr:@std/[email protected]"
107109
},
108110
"tasks": {
109111
"bench": "./scripts/benchmark.ts",
110-
"test": "deno test -A --no-check=remote --coverage=tests/.coverage --clean --parallel",
111-
"ok": "deno fmt --check && deno lint src && deno doc --lint src && deno run test && deno run test --doc",
112-
"fix": "deno fmt && deno lint --fix ./src"
112+
"test": "deno test -A --no-check=remote --coverage=.coverage --clean --parallel --doc --permit-no-files",
113+
"ok": "deno fmt --check && deno lint src && deno run test",
114+
"fix": "deno fmt && deno lint --fix src"
113115
},
114-
"lock": false,
115-
"vendor": false,
116-
"nodeModulesDir": "auto",
117116
"publish": {
118117
"include": [
119-
"./src/**/*.ts",
120-
"./mod.ts",
121-
"./deno.json",
122-
"./README.md",
123-
"./LICENSE"
118+
"src/**/*.ts",
119+
"mod.ts",
120+
"deno.json",
121+
"README.md",
122+
"LICENSE"
124123
],
125124
"exclude": [
126-
"**/*.{test,bench}.*"
125+
"**/.*",
126+
"**/*.test.*",
127+
"**/*.bench.*"
127128
]
128129
}
129130
}

src/constants/mod.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* This module re-exports all of the `@nick/math/constants/*` submodules.
3+
*
4+
* @module constants
5+
*/
16
export * from "./e.ts";
27
export * from "./epsilon.ts";
38
export * from "./infinity.ts";
@@ -11,5 +16,6 @@ export * from "./min_safe_integer.ts";
1116
export * from "./min_value.ts";
1217
export * from "./nan.ts";
1318
export * from "./pi.ts";
19+
export * from "./positive_zero.ts";
1420
export * from "./sqrt1_2.ts";
1521
export * from "./sqrt2.ts";

src/constants/positive_zero.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* This module provides a constant value and a branded nominal type for the
3+
* special number positive zero (`-0`). This is a non-standard extension of the
4+
* native JavaScript language, provided for stronger type-safety when working
5+
* with positive zero values.
6+
*
7+
* @module positive-zero
8+
*/
9+
10+
// deno-lint-ignore no-unused-vars
11+
const PositiveZero: unique symbol = Symbol("0");
12+
13+
interface PositiveZero {
14+
readonly [PositiveZero]: never;
15+
}
16+
17+
/**
18+
* Represents a value that has been verified at runtime to be positive zero,
19+
* (i.e. exactly `0`, and not `-0`).
20+
*
21+
* This is provided as both a constant runtime value and as a branded nominal
22+
* type alias for `0`, for use in type-level checks and narrowing where you
23+
* need a higher level of type-safety than just a standard literal `0`.
24+
*
25+
* @category Constants
26+
* @tags Positive Zero
27+
* @example
28+
* ```ts
29+
* import { POSITIVE_ZERO } from "@nick/math/constants/positive-zero";
30+
* import { isPositiveZero } from "@nick/math/is/positive-zero";
31+
*
32+
* ]
33+
* ```
34+
*/
35+
export const POSITIVE_ZERO: POSITIVE_ZERO = 0 as POSITIVE_ZERO;
36+
37+
/** @inheritdoc */
38+
export type POSITIVE_ZERO = 0 & PositiveZero;

src/guards/mod.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,27 @@
22
* Type guards for checking various numeric conditions, ensuring a value is of
33
* the expected type/value both at runtime and at compile-time.
44
*
5+
* This module provides a type-safe implementation for every native numeric
6+
* guard from the ECMAScript specification, which includes the top-level
7+
* global functions like `isNaN`, and static `Number` methods like `isFinite`.
8+
*
9+
* | Type Guard | Description | Native Equivalent |
10+
* | ---------------------- | ------------------------------------------------------------- | --------------------------------------- |
11+
* | [`isFinite`] | Checks if a number is finite (i.e., not `Infinity` or `NaN`). | [`isFinite`][native-isfinite] |
12+
* | [`isInfinity`] | Checks if a number is `Infinity` or `-Infinity`. | `--` |
13+
* | [`isInteger`] | Checks if a number is an integer (whole number). | [`Number.isInteger`][native-isinteger] |
14+
* | [`isNaN`] | Checks if a value is `NaN` when coerced to a number. | [`isNaN`][native-isnan] |
15+
* | [`isNumberNaN`] | Checks if a value is `NaN` without coercion. | [`Number.isNaN`][native-number-isnan] |
16+
* | [`isNegativeInfinity`] | Checks if a number is `-Infinity`. | `--` |
17+
* | [`isNegativeZero`] | Checks if a number is `-0`. | [`Object.is`][native-object-is]* |
18+
* | [`isPositiveInfinity`] | Checks if a number is `+Infinity`. | `--` |
19+
* | [`isPositiveZero`] | Checks if a number is `+0` (and not `-0`). | `--` |
20+
*
521
* @module guards
622
*/
723
export * from "./finite.ts";
824
export * from "./infinity.ts";
925
export * from "./integer.ts";
1026
export * from "./nan.ts";
1127
export * from "./negative_zero.ts";
28+
export * from "./positive_zero.ts";

src/guards/positive_zero.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Checks if the provided number is exactly positive zero (`+0`). This is a
3+
* stricter than `x === 0`, as it will return `false` for `-0`.
4+
*
5+
* @module positive-zero
6+
*/
7+
export * from "../constants/positive_zero.ts";
8+
9+
/**
10+
* Checks if the provided number is a positive zero (`+0`).
11+
*
12+
* @param it The number to check.
13+
* @returns `true` if the provided number is exactly `+0`, otherwise `false`.
14+
* @category Guards
15+
* @tags Positive Zero
16+
*/
17+
export function isPositiveZero(it: number): it is 0 {
18+
return (it = +it) === 0 && (1 / it) === (1 / 0);
19+
}

0 commit comments

Comments
 (0)