Skip to content

Commit

Permalink
Merge 7ad4d21 into b354aec
Browse files Browse the repository at this point in the history
  • Loading branch information
micnic committed Mar 3, 2023
2 parents b354aec + 7ad4d21 commit 1e83bb6
Show file tree
Hide file tree
Showing 28 changed files with 606 additions and 257 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"no-magic-numbers": [
"error",
{
"ignore": [-1, 0, 1, "-1n", "0n", "1n"],
"ignore": [-2, -1, 0, 1, 2, "-2n", "-1n", "0n", "1n", "2n"],
"detectObjects": true,
"enforceConst": true,
"ignoreArrayIndexes": true
Expand Down
6 changes: 5 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ const invalidSchema = 'Invalid schema argument type, object expected';
const getSource = (sources) => {

// Check for one source object
if (hasOneElement(sources) && typeof sources[0] === 'object') {
if (
hasOneElement(sources) &&
typeof sources[0] === 'object' &&
sources[0] !== null
) {
return sources[0];
}

Expand Down
4 changes: 2 additions & 2 deletions lib/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ const isAnyDate = (value) => (value instanceof Date);
// Save type guard meta
setTypeGuardMeta(isAnyDate, {
annotation: 'Date',
builder: Date,
classification: 'instance',
constructor: Date,
description: 'an instance of Date'
});

Expand Down Expand Up @@ -59,8 +59,8 @@ const isDate = (value) => (isAnyDate(value) && !isNaN(value.getTime()));
// Save type guard meta
setTypeGuardMeta(isDate, {
annotation: 'Date',
builder: Date,
classification: 'instance',
constructor: Date,
description: 'an instance of valid Date'
});

Expand Down
13 changes: 12 additions & 1 deletion lib/function.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import type {
BaseTypeGuard,
InferAsyncFunction,
InferFunction,
Tuple,
TypeGuard
} from 'r-assign/lib';

/**
* Check for async function values
*/
declare function isAsyncFunction<
T extends Tuple,
R extends TypeGuard = TypeGuard<void>
>(args: T, result?: BaseTypeGuard<R>): TypeGuard<InferAsyncFunction<T, R>>;

/**
* Check for function values
*/
Expand All @@ -14,8 +23,10 @@ declare function isFunction<
>(args: T, result?: BaseTypeGuard<R>): TypeGuard<InferFunction<T, R>>;

export {
isAsyncFunction,
isAsyncFunction as asyncFunc,
isFunction,
isFunction as func
};

export type { InferFunction };
export type { InferAsyncFunction, InferFunction };
71 changes: 43 additions & 28 deletions lib/function.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
const {
assertBaseTypeGuard,
getTypeGuardMeta,
getVoidableTypeGuardMeta,
setTypeGuardMeta
} = require('r-assign/lib/internal/type-guard-meta');
const { isPromiseOf } = require('r-assign/lib/promise');
const { isTupleOf } = require('r-assign/lib/tuple');

/**
Expand All @@ -21,21 +23,28 @@ const { isTupleOf } = require('r-assign/lib/tuple');
* @typedef {import('r-assign/lib').Tuple} Tuple
*/

/**
* @template {Tuple} A
* @template {TypeGuard} R
* @typedef {import('r-assign/lib').InferAF<A, R>} InferAsyncFunction
*/

/**
* @template {Tuple} A
* @template {TypeGuard} R
* @typedef {import('r-assign/lib').InferF<A, R>} InferFunction
*/

/**
* @typedef {import('r-assign/lib/internal').TGM} TypeGuardMeta
*/

/**
* Get input annotation
* @template {TypeGuard} I
* @param {I} input
* @param {TypeGuardMeta} meta
* @returns {string}
*/
const getInputAnnotation = (input) => {

const meta = getTypeGuardMeta(input);
const getInputAnnotation = (meta) => {

// Switch on input classification
switch (meta.classification) {
Expand Down Expand Up @@ -80,36 +89,27 @@ const getInputAnnotation = (input) => {

/**
* Get output annotation
* @template {TypeGuard} O
* @param {O} [output]
* @param {TypeGuardMeta} meta
* @returns {string}
*/
const getOutputAnnotation = (output) => {

// Check for non-void output
if (output) {
const getOutputAnnotation = (meta) => {

const { annotation, classification } = getTypeGuardMeta(output);
// Assert for base type guard
assertBaseTypeGuard(meta.classification);

// Assert for base type guard
assertBaseTypeGuard(classification);

return annotation;
}

return 'void';
return meta.annotation;
};

/**
* Get function annotation
* @template {TypeGuard} I
* @template {TypeGuard} O
* @param {I} input
* @param {O} [output]
* @param {TypeGuardMeta} inputMeta
* @param {TypeGuardMeta} outputMeta
* @returns {string}
*/
const getFunctionAnnotation = (input, output) => {
return `(${getInputAnnotation(input)}) => ${getOutputAnnotation(output)}`;
const getFunctionAnnotation = (inputMeta, outputMeta) => {
return `(${getInputAnnotation(inputMeta)}) => ${getOutputAnnotation(
outputMeta
)}`;
};

/**
Expand All @@ -123,24 +123,39 @@ const getFunctionAnnotation = (input, output) => {
const isFunction = (input, output) => {

const isInput = isTupleOf(input);
const annotation = getFunctionAnnotation(isInput, output);
const inputMeta = getTypeGuardMeta(isInput);
const outputMeta = getVoidableTypeGuardMeta(output);
const annotation = getFunctionAnnotation(inputMeta, outputMeta);

/** @type {TypeGuard<InferFunction<I, O>>} */
const check = (value) => (typeof value === 'function');

// Save type guard meta
setTypeGuardMeta(check, {
annotation,
children: [inputMeta, outputMeta],
classification: 'function',
description: `a function ${annotation}`,
input: isInput,
output
types: [isInput, output]
});

return check;
};

/**
* Check for async function values
* @template {Tuple} I
* @template {TypeGuard} O
* @param {I} input
* @param {BaseTypeGuard<O>} [output]
* @returns {TypeGuard<InferAsyncFunction<I, O>>}
*/
const isAsyncFunction = (input, output) =>
isFunction(input, isPromiseOf(output));

module.exports = {
asyncFunc: isAsyncFunction,
func: isFunction,
isAsyncFunction,
isFunction
};
10 changes: 5 additions & 5 deletions lib/get-type.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

const { invalidInitialValue } = require('r-assign/lib/internal/invalid-type');
const { refineValue, takeValue } = require('r-assign/lib/internal/pick-value');
const { pickValue, refineValue } = require('r-assign/lib/internal/pick-value');
const {
assertBaseTypeGuard,
getTypeGuardMeta
Expand Down Expand Up @@ -59,21 +59,21 @@ const getType = (type, initial, refine) => {

// Check for valid value type
if (type(value)) {
return refineValue(takeValue(value, meta), type, refine);
return refineValue(pickValue(value, meta), type, refine);
}

return refineValue(takeValue(initial, meta), type, refine);
return refineValue(pickValue(initial, meta), type, refine);
};
}

return (value) => {

// Check for valid value type
if (type(value)) {
return takeValue(value, meta);
return pickValue(value, meta);
}

return takeValue(initial, meta);
return pickValue(initial, meta);
};
};

Expand Down

0 comments on commit 1e83bb6

Please sign in to comment.