74 lines
1.6 KiB
JavaScript
74 lines
1.6 KiB
JavaScript
import { BIGINT, BOOLEAN, FUNCTION, NULL, NUMBER, OBJECT, STRING, SYMBOL, UNDEFINED } from './types.js';
|
|
|
|
const { isArray } = Array;
|
|
|
|
export { isArray };
|
|
|
|
export const invoke = value => /** @type {Function} */ (value)();
|
|
|
|
/**
|
|
* @template Value
|
|
* @param {string} type
|
|
* @param {Value} value
|
|
* @returns {Value}
|
|
*/
|
|
export const reviver = (type, value) => value;
|
|
|
|
/**
|
|
* @template V
|
|
* @typedef {[V]} Arr
|
|
*/
|
|
|
|
/**
|
|
* @template V
|
|
* @typedef {() => V} Ctx
|
|
*/
|
|
|
|
/**
|
|
* @template T, V
|
|
* @typedef {{t:T, v:V}} Obj
|
|
*/
|
|
|
|
/**
|
|
* @template V
|
|
* @typedef {V extends bigint ? BIGINT : V extends boolean ? BOOLEAN : V extends null ? NULL : V extends number ? NUMBER : V extends string ? STRING : V extends symbol ? SYMBOL : V extends undefined ? UNDEFINED : V extends object ? OBJECT : never} TypeOf
|
|
*/
|
|
|
|
/**
|
|
* @template T, V
|
|
* @param {T} t
|
|
* @param {V} v
|
|
* @returns {Obj<T, V>}
|
|
*/
|
|
export const obj = (t, v) => ({t, v});
|
|
|
|
/**
|
|
* @template V
|
|
* @param {V} value
|
|
* @returns {Ctx<V>}
|
|
*/
|
|
export const bound = value => Context.bind(value);
|
|
|
|
/**
|
|
* @template V, T
|
|
* @param {V} value
|
|
* @returns {V extends Ctx<T> ? ReturnType<V> : V}
|
|
*/
|
|
export const unbound = value => (
|
|
typeof value === FUNCTION ? invoke(value) : value
|
|
);
|
|
|
|
// This is needed to unlock *both* apply and construct
|
|
// traps otherwise one of these might fail.
|
|
// The 'use strict' directive is needed to allow
|
|
// also primitive types to be bound.
|
|
function Context() {
|
|
'use strict';
|
|
return this;
|
|
}
|
|
|
|
// TODO: is this really needed in here?
|
|
// const { hasOwn } = Object;
|
|
// const isConstructable = value => hasOwn(value, 'prototype');
|
|
// const isFunction = value => typeof value === FUNCTION;
|