Skip to content

Commit 93987da

Browse files
authored
Merge pull request #4 from nberlette/refactor/typed-array
refactor/typed array
2 parents b78945d + 742bd7c commit 93987da

File tree

11 files changed

+387
-102
lines changed

11 files changed

+387
-102
lines changed

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nick/is",
3-
"version": "0.2.0-rc.3",
3+
"version": "0.2.0-rc.4",
44
"license": "MIT",
55
"author": {
66
"name": "Nicholas Berlette",

src/_internal/has_methods.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* @see https://jsr.io/@nick/[email protected]/doc/has-methods
66
*/
77

8+
import { Object } from "./primordials.ts";
9+
810
/**
911
* Composite type guard that checks if the given value {@linkcode it} contains
1012
* all the specified {@linkcode keys}, and also that each is a callable method.

src/_internal/is_tagged_native.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* @see https://jsr.io/@nick/[email protected]/doc/is-tagged-native
66
*/
77

8+
import { Object, SymbolToStringTag } from "./primordials.ts";
89
import { toString } from "./to_string.ts";
910

1011
/**
@@ -32,7 +33,7 @@ export function isTaggedNative<U extends {}, T extends string>(
3233
tag = tag.toString().replace(/^\[object (.+)\]$/, "$1") as T;
3334
return toString(it = Object(it)) === `[object ${tag}]` &&
3435
(allowCustom
35-
? Symbol.toStringTag in it && it[Symbol.toStringTag] === tag
36-
: typeof (it as Record<symbol, unknown>)[Symbol.toStringTag] ===
37-
"undefined");
36+
? SymbolToStringTag in it && it[SymbolToStringTag] === tag
37+
// deno-lint-ignore no-explicit-any
38+
: typeof (it as any)[SymbolToStringTag] === "undefined");
3839
}

src/_internal/primordials.ts

Lines changed: 118 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,127 @@
1+
// deno-lint-ignore-file no-explicit-any
12
/*!
23
* Copyright (c) 2024-2025 Nicholas Berlette. All rights reserved.
34
* @license MIT (https://nick.mit-license.org/2024)
45
* @see https://jsr.io/@nick/[email protected]/doc/primordials
56
*/
67
import { $globalThis } from "./global_this.ts";
8+
import type * as T from "./types.ts";
79

8-
export const Array = $globalThis.Array;
9-
export const Object = $globalThis.Object;
10-
export const Function = $globalThis.Function;
11-
export const String = $globalThis.String;
12-
export const Number = $globalThis.Number;
13-
export const Boolean = $globalThis.Boolean;
14-
export const Date = $globalThis.Date;
15-
export const RegExp = $globalThis.RegExp;
16-
export const Error = $globalThis.Error;
17-
export const Symbol = $globalThis.Symbol;
10+
export const Array: ArrayConstructor = $globalThis.Array;
11+
export const String: StringConstructor = $globalThis.String;
12+
export const Number: NumberConstructor = $globalThis.Number;
13+
export const Boolean: BooleanConstructor = $globalThis.Boolean;
14+
export const Date: DateConstructor = $globalThis.Date;
15+
export const RegExp: RegExpConstructor = $globalThis.RegExp;
16+
17+
export const Object: ObjectConstructor = $globalThis.Object;
18+
export const ObjectPrototype: Object = Object.prototype;
19+
export const ObjectKeys: <O>(o: O) => T.ObjectKeys<O> = Object.keys;
20+
export const ObjectValues: <O>(o: O) => T.ObjectValues<O> = Object.values;
21+
export const ObjectEntries: <O>(o: O) => T.ObjectEntries<O> = Object.entries;
22+
export const ObjectGetPrototypeOf: (o: any) => any = Object.getPrototypeOf;
23+
export const ObjectGetOwnPropertyDescriptor: <O, K extends keyof any>(
24+
o: O,
25+
k: K,
26+
) =>
27+
| (
28+
& TypedPropertyDescriptor<K extends keyof O ? O[K] : any>
29+
& ThisType<O>
30+
)
31+
| undefined = Object.getOwnPropertyDescriptor;
32+
33+
export const Symbol: SymbolConstructor = $globalThis.Symbol;
1834
export const SymbolFor: typeof Symbol.for = Symbol.for;
1935
export const SymbolKeyFor: typeof Symbol.keyFor = Symbol.keyFor;
20-
export const SymbolToStringTag: typeof Symbol.toStringTag = Symbol.toStringTag;
21-
export const SymbolIterator: typeof Symbol.iterator = Symbol.iterator;
22-
export const SymbolAsyncIterator: typeof Symbol.asyncIterator =
23-
Symbol.asyncIterator;
24-
export const SymbolHasInstance: typeof Symbol.hasInstance = Symbol.hasInstance;
25-
export const TypeError = $globalThis.TypeError;
26-
export const ReferenceError = $globalThis.ReferenceError;
27-
export const SyntaxError = $globalThis.SyntaxError;
28-
export const RangeError = $globalThis.RangeError;
29-
export const EvalError = $globalThis.EvalError;
30-
export const URIError = $globalThis.URIError;
31-
export const Proxy = $globalThis.Proxy;
32-
export const Reflect = $globalThis.Reflect;
33-
export const Set = $globalThis.Set;
34-
export const Map = $globalThis.Map;
35-
export const WeakMap = $globalThis.WeakMap;
36-
export const WeakSet = $globalThis.WeakSet;
37-
export const ArrayBuffer = $globalThis.ArrayBuffer;
38-
export const DataView = $globalThis.DataView;
39-
export const Int8Array = $globalThis.Int8Array;
40-
export const Uint8Array = $globalThis.Uint8Array;
41-
export const Uint8ClampedArray = $globalThis.Uint8ClampedArray;
42-
export const Int16Array = $globalThis.Int16Array;
43-
export const Uint16Array = $globalThis.Uint16Array;
44-
export const Int32Array = $globalThis.Int32Array;
45-
export const Uint32Array = $globalThis.Uint32Array;
46-
export const Float16Array = $globalThis.Float16Array;
47-
export const Float32Array = $globalThis.Float32Array;
48-
export const Float64Array = $globalThis.Float64Array;
49-
export const BigInt64Array = $globalThis.BigInt64Array;
50-
export const BigUint64Array = $globalThis.BigUint64Array;
36+
export const SymbolToStringTag: SymbolToStringTag = Symbol.toStringTag;
37+
export type SymbolToStringTag = typeof Symbol.toStringTag;
38+
export const SymbolIterator: SymbolIterator = Symbol.iterator;
39+
export type SymbolIterator = typeof Symbol.iterator;
40+
export const SymbolAsyncIterator: SymbolAsyncIterator = Symbol.asyncIterator;
41+
export type SymbolAsyncIterator = typeof Symbol.asyncIterator;
42+
export const SymbolHasInstance: SymbolHasInstance = Symbol.hasInstance;
43+
export type SymbolHasInstance = typeof Symbol.hasInstance;
44+
export const SymbolDispose: SymbolDispose = Symbol.dispose;
45+
export type SymbolDispose = typeof Symbol.dispose;
46+
export const SymbolAsyncDispose: SymbolAsyncDispose = Symbol.asyncDispose;
47+
export type SymbolAsyncDispose = typeof Symbol.asyncDispose;
48+
export const SymbolMetadata: SymbolMetadata = Symbol.metadata;
49+
export type SymbolMetadata = typeof Symbol.metadata;
50+
export const SymbolIsConcatSpreadable: SymbolIsConcatSpreadable = Symbol
51+
.isConcatSpreadable;
52+
export type SymbolIsConcatSpreadable = typeof Symbol.isConcatSpreadable;
53+
54+
export const Function: FunctionConstructor = $globalThis.Function;
55+
export const FunctionPrototype: Function = Function.prototype;
56+
export type FunctionPrototype = typeof Function.prototype;
57+
58+
export const {
59+
bind,
60+
call,
61+
apply,
62+
toString,
63+
[SymbolHasInstance]: hasInstance,
64+
} = FunctionPrototype;
65+
66+
export const uncurryThis = bind.bind(call) as <
67+
T,
68+
const A extends readonly unknown[],
69+
R = unknown,
70+
>(fn: (this: T, ...args: A) => R) => (target: T, ...args: A) => R;
71+
72+
export const FunctionPrototypeBind = uncurryThis(
73+
bind as CallableFunction["bind"],
74+
);
75+
export const FunctionPrototypeCall = uncurryThis(
76+
call as CallableFunction["call"],
77+
);
78+
export const FunctionPrototypeApply = uncurryThis(
79+
apply as CallableFunction["apply"],
80+
);
81+
export const FunctionPrototypeToString = uncurryThis(
82+
toString as CallableFunction["toString"],
83+
);
84+
export const FunctionPrototypeHasInstance = uncurryThis(
85+
hasInstance as CallableFunction[SymbolHasInstance],
86+
);
87+
88+
export const Error: ErrorConstructor = $globalThis.Error;
89+
export const ErrorCaptureStackTrace: typeof Error.captureStackTrace =
90+
Error.captureStackTrace;
91+
export const TypeError: TypeErrorConstructor = $globalThis.TypeError;
92+
export const ReferenceError: ReferenceErrorConstructor =
93+
$globalThis.ReferenceError;
94+
export const SyntaxError: SyntaxErrorConstructor = $globalThis.SyntaxError;
95+
export const RangeError: RangeErrorConstructor = $globalThis.RangeError;
96+
export const EvalError: EvalErrorConstructor = $globalThis.EvalError;
97+
export const URIError: URIErrorConstructor = $globalThis.URIError;
98+
99+
export const Reflect: typeof $globalThis.Reflect = $globalThis.Reflect;
100+
export const Atomics: typeof $globalThis.Atomics = $globalThis.Atomics;
101+
102+
export const Proxy: ProxyConstructor = $globalThis.Proxy;
103+
export const Set: SetConstructor = $globalThis.Set;
104+
export const Map: MapConstructor = $globalThis.Map;
105+
export const WeakMap: WeakMapConstructor = $globalThis.WeakMap;
106+
export const WeakSet: WeakSetConstructor = $globalThis.WeakSet;
107+
export const WeakRef: WeakRefConstructor = $globalThis.WeakRef;
108+
109+
export const ArrayBuffer: ArrayBufferConstructor = $globalThis.ArrayBuffer;
110+
export const SharedArrayBuffer: SharedArrayBufferConstructor =
111+
$globalThis.SharedArrayBuffer;
112+
export const DataView: DataViewConstructor = $globalThis.DataView;
113+
export const Int8Array: Int8ArrayConstructor = $globalThis.Int8Array;
114+
export const Int16Array: Int16ArrayConstructor = $globalThis.Int16Array;
115+
export const Int32Array: Int32ArrayConstructor = $globalThis.Int32Array;
116+
export const Uint8Array: Uint8ArrayConstructor = $globalThis.Uint8Array;
117+
export const Uint8ClampedArray: Uint8ClampedArrayConstructor =
118+
$globalThis.Uint8ClampedArray;
119+
export const Uint16Array: Uint16ArrayConstructor = $globalThis.Uint16Array;
120+
export const Uint32Array: Uint32ArrayConstructor = $globalThis.Uint32Array;
121+
export const Float16Array: Float16ArrayConstructor = $globalThis.Float16Array;
122+
export const Float32Array: Float32ArrayConstructor = $globalThis.Float32Array;
123+
export const Float64Array: Float64ArrayConstructor = $globalThis.Float64Array;
124+
export const BigInt64Array: BigInt64ArrayConstructor =
125+
$globalThis.BigInt64Array;
126+
export const BigUint64Array: BigUint64ArrayConstructor =
127+
$globalThis.BigUint64Array;

src/_internal/to_string.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import { uncurryThis } from "./uncurry_this.ts";
8+
import { Object } from "./primordials.ts";
89

910
/**
1011
* An uncurried version of the `Object.prototype.toString` method, which allows

src/_internal/try_method.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* @see https://jsr.io/@nick/[email protected]/doc/try-method
55
*/
66

7+
import { FunctionPrototypeCall } from "./primordials.ts";
8+
79
/**
810
* Attempt to call a given {@link method} on the provided {@link prototype}
911
* object, with the given {@link it} as the contextual `this` binding.
@@ -15,13 +17,13 @@ export function tryMethod<
1517
A extends readonly unknown[] = Parameters<T[M]>,
1618
R = ReturnType<T[M]>,
1719
>(
18-
prototype: T | { [K in M]: (this: T, ...args: A) => R },
20+
prototype: { [K in M]: (this: T, ...args: A) => R },
1921
method: M,
2022
it: unknown,
2123
): it is T {
2224
try {
2325
if (method in prototype && typeof prototype[method] === "function") {
24-
prototype[method].call?.(it);
26+
FunctionPrototypeCall(prototype[method], it as T);
2527
return true;
2628
}
2729
} catch { /* ignore */ }

src/_internal/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ export type unknowns = {} | null | undefined;
4545

4646
export type Expand<T, Fallback = never> = T extends infer T ? T : Fallback;
4747

48+
export type ObjectEntry<T> = { [K in keyof T]: [K, T[K]] }[keyof T];
49+
export type ObjectEntries<T> = ObjectEntry<T>[];
50+
export type ObjectKeys<T> = (string & keyof T)[];
51+
export type ObjectValues<T> = T[keyof T][];
52+
4853
export type Split<
4954
S extends string,
5055
C extends string = "",

src/_internal/uncurry_getter.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44
* @see https://jsr.io/@nick/[email protected]/doc/uncurry-getter
55
*/
66

7-
import { bind, call } from "./uncurry_this.ts";
7+
import {
8+
bind,
9+
call,
10+
ErrorCaptureStackTrace,
11+
FunctionPrototypeCall,
12+
ObjectGetOwnPropertyDescriptor,
13+
String,
14+
TypeError,
15+
} from "./primordials.ts";
816

917
/** @internal */
1018
export function uncurryGetter<
@@ -33,7 +41,7 @@ export function uncurryGetter(
3341
assert?: boolean | "stub",
3442
message?: string,
3543
): ((self: object) => unknown) | undefined {
36-
if (typeof target !== "object") {
44+
if (typeof target !== "object" || target === null) {
3745
if (assert === "stub") {
3846
return () => {
3947
throw new TypeError(message ?? "Target must be an object.");
@@ -42,14 +50,21 @@ export function uncurryGetter(
4250
throw new TypeError("Target must be an object.");
4351
}
4452
} else {
45-
const desc = Object.getOwnPropertyDescriptor(target, key);
46-
if (desc?.get) return bind.call(call, desc.get);
53+
const desc = ObjectGetOwnPropertyDescriptor(target, key);
54+
// if (desc?.get) return bind.call(call, desc.get);
55+
if (desc?.get) {
56+
return FunctionPrototypeCall(
57+
bind,
58+
call,
59+
desc.get,
60+
);
61+
}
4762
if (assert) {
4863
if (!message) {
49-
message = `Property '${key.toString()}' is not a getter.`;
64+
message = `Property '${String(key)}' is not a getter.`;
5065
}
5166
const error = new TypeError(message);
52-
Error.captureStackTrace?.(error, uncurryGetter);
67+
ErrorCaptureStackTrace?.(error, uncurryGetter);
5368
error.stack; // trigger lazy stack capture
5469
throw error;
5570
}

src/_internal/uncurry_this.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,8 @@
44
* @see https://jsr.io/@nick/[email protected]/doc/uncurry-this
55
*/
66

7-
export const { bind, call } = Function.prototype;
7+
import { FunctionPrototype, uncurryThis } from "./primordials.ts";
88

9-
export const uncurryThis = bind.bind(call) as <
10-
T,
11-
// deno-lint-ignore no-explicit-any
12-
const A extends readonly unknown[] = any[],
13-
R = unknown,
14-
>(
15-
fn: (this: T, ...args: A) => R,
16-
) => (target: T, ...args: Parameters<typeof fn>) => ReturnType<typeof fn>;
9+
export const { bind, call } = FunctionPrototype;
10+
11+
export { uncurryThis };

src/enum.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
* @see https://jsr.io/@nick/[email protected]/doc/enum
55
*/
66

7+
import type { unknowns } from "./_internal/types.ts";
8+
import {
9+
ObjectGetPrototypeOf,
10+
ObjectKeys,
11+
ObjectPrototype,
12+
} from "./_internal/primordials.ts";
13+
714
/**
815
* @module enum
916
*
@@ -28,11 +35,6 @@
2835
* ```
2936
* @category Objects
3037
*/
31-
const Object = globalThis.Object;
32-
const ObjectPrototype = Object.prototype;
33-
const ObjectKeys = Object.keys as <T>(o: T) => (string & keyof T)[];
34-
// const ObjectValues = Object.values;
35-
const ObjectGetPrototypeOf = Object.getPrototypeOf;
3638

3739
/**
3840
* Check if the given value appears to be a TypeScript `enum` object, which is
@@ -62,10 +64,7 @@ const ObjectGetPrototypeOf = Object.getPrototypeOf;
6264
* ```
6365
* @category Objects
6466
*/
65-
export function isEnum<T extends EnumLike = EnumLike>(
66-
// deno-lint-ignore ban-types
67-
it: T | {} | null | undefined,
68-
): it is Enum<T>;
67+
export function isEnum<T extends EnumLike>(it: T | unknowns): it is Enum<T>;
6968
export function isEnum<T extends EnumLike = EnumLike>(
7069
it: unknown,
7170
): it is Enum<T>;

0 commit comments

Comments
 (0)