Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More β†’
Socket
Sign inDemoInstall
Socket

typescript-is

Package Overview
Dependencies
Maintainers
1
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typescript-is - npm Package Compare versions

Comparing version 0.18.3 to 0.19.0

2

index.d.ts

@@ -128,3 +128,3 @@ /**

*/
export function AssertType(): (target: object, propertyKey: string | symbol, parameterIndex: number) => void;
export function AssertType(options?: { async: boolean }): (target: object, propertyKey: string | symbol, parameterIndex: number) => void;

@@ -131,0 +131,0 @@ /**

@@ -22,2 +22,4 @@ let defaultGetErrorObject = undefined;

function appendInputToErrorMessage(message, path, inputObject) {
if (message === undefined)
return 'validation error';
const foundInputObject = inputObjectAtPath(path, inputObject);

@@ -49,3 +51,7 @@ try {

const assertions = Reflect.getOwnMetadata(assertionsMetadataKey, target, propertyKey) || [];
assertions[parameterIndex] = { assertion, options };
if(Reflect.getOwnMetadata('design:returntype', target, propertyKey) === Promise) {
assertions[parameterIndex] = { assertion, options: Object.assign({ async: true }, options) };
} else {
assertions[parameterIndex] = { assertion, options };
}
Reflect.defineMetadata(assertionsMetadataKey, assertions, target, propertyKey);

@@ -69,3 +75,8 @@ };

if (errorObject !== null) {
throw new errorConstructor(errorObject, args[i]);
const errorInstance = new errorConstructor(errorObject, args[i]);
if(assertions[i].options.async) {
return Promise.reject(errorInstance);
} else {
throw errorInstance;
}
}

@@ -72,0 +83,0 @@ }

@@ -12,3 +12,5 @@ "use strict";

const functionNames = new Set();
const visitorContext = Object.assign(Object.assign({}, partialVisitorContext), { functionNames, functionMap });
const typeIdMap = new Map();
const visitorContext = Object.assign(Object.assign({}, partialVisitorContext), { functionNames, functionMap, typeIdMap });
const emitDetailedErrors = !!visitorContext.options.emitDetailedErrors;
const functionName = partialVisitorContext.options.shortCircuit

@@ -19,11 +21,13 @@ ? visitor_type_check_1.visitShortCircuit(visitorContext)

: visitor_type_check_1.visitType(type, visitorContext));
const errorIdentifier = ts.createIdentifier('error');
const declarations = utils_1.sliceMapValues(functionMap);
const variableDeclarations = [];
if (emitDetailedErrors) {
variableDeclarations.push(ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [ts.createVariableDeclaration(VisitorUtils.pathIdentifier, undefined, ts.createArrayLiteral([ts.createStringLiteral(rootName)]))]));
}
const functionDeclarations = utils_1.sliceMapValues(functionMap);
return ts.createArrowFunction(undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, VisitorUtils.objectIdentifier, undefined, ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))
], undefined, undefined, ts.createBlock([
ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [ts.createVariableDeclaration(VisitorUtils.pathIdentifier, undefined, ts.createArrayLiteral([ts.createStringLiteral(rootName)]))]),
...declarations,
ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [ts.createVariableDeclaration(errorIdentifier, undefined, ts.createCall(ts.createIdentifier(functionName), undefined, [VisitorUtils.objectIdentifier]))]),
ts.createReturn(errorIdentifier)
...variableDeclarations,
...functionDeclarations,
ts.createReturn(ts.createCall(ts.createIdentifier(functionName), undefined, [VisitorUtils.objectIdentifier]))
]));

@@ -65,5 +69,7 @@ }

const isEquals = name === 'equals' || name === 'createEquals' || name === 'assertEquals' || name === 'createAssertEquals';
const isAssert = name === 'assertEquals' || name === 'assertType' || name === 'createAssertEquals' || name === 'createAssertType';
const emitDetailedErrors = visitorContext.options.emitDetailedErrors === 'auto' ? isAssert : visitorContext.options.emitDetailedErrors;
const typeArgument = node.typeArguments[0];
const type = visitorContext.checker.getTypeFromTypeNode(typeArgument);
const arrowFunction = createArrowFunction(type, extractVariableName(node.arguments[0]), false, Object.assign(Object.assign({}, visitorContext), { options: Object.assign(Object.assign({}, visitorContext.options), { disallowSuperfluousObjectProperties: isEquals || visitorContext.options.disallowSuperfluousObjectProperties }) }));
const arrowFunction = createArrowFunction(type, extractVariableName(node.arguments[0]), false, Object.assign(Object.assign({}, visitorContext), { options: Object.assign(Object.assign({}, visitorContext.options), { disallowSuperfluousObjectProperties: isEquals || visitorContext.options.disallowSuperfluousObjectProperties, emitDetailedErrors }) }));
return ts.updateCall(node, node.expression, node.typeArguments, [

@@ -75,2 +81,7 @@ ...node.arguments,

}
else if (visitorContext.options.transformNonNullExpressions && ts.isNonNullExpression(node)) {
const expression = node.expression;
return ts.factory.updateNonNullExpression(node, ts.factory.createParenthesizedExpression(ts.factory.createConditionalExpression(ts.factory.createParenthesizedExpression(ts.factory.createBinaryExpression(ts.factory.createBinaryExpression(ts.factory.createTypeOfExpression(expression), ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createStringLiteral('undefined')), ts.factory.createToken(ts.SyntaxKind.BarBarToken), ts.factory.createBinaryExpression(expression, ts.factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.factory.createNull()))), ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createCallExpression(ts.factory.createParenthesizedExpression(ts.factory.createArrowFunction(undefined, undefined, [], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createBlock([ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier('Error'), undefined, [ts.factory.createTemplateExpression(ts.factory.createTemplateHead(`${expression.getText()} was non-null asserted but is `), [ts.factory.createTemplateSpan(expression, ts.factory.createTemplateTail(''))])]))
], false))), undefined, []), ts.factory.createToken(ts.SyntaxKind.ColonToken), expression)));
}
return node;

@@ -77,0 +88,0 @@ }

@@ -21,2 +21,10 @@ "use strict";

}
function getEmitDetailedErrors(options) {
if (options) {
if (options.emitDetailedErrors === 'auto' || typeof options.emitDetailedErrors === 'boolean') {
return options.emitDetailedErrors;
}
}
return 'auto';
}
function transformer(program, options) {

@@ -35,3 +43,5 @@ if (options && options.verbose) {

functionBehavior: getFunctionBehavior(options),
disallowSuperfluousObjectProperties: !!(options && options.disallowSuperfluousObjectProperties)
disallowSuperfluousObjectProperties: !!(options && options.disallowSuperfluousObjectProperties),
transformNonNullExpressions: !!(options && options.transformNonNullExpressions),
emitDetailedErrors: getEmitDetailedErrors(options)
},

@@ -38,0 +48,0 @@ typeMapperStack: [],

@@ -9,2 +9,4 @@ import * as ts from 'typescript';

disallowSuperfluousObjectProperties: boolean;
transformNonNullExpressions: boolean;
emitDetailedErrors: boolean | 'auto';
}

@@ -15,2 +17,4 @@

functionMap: Map<string, ts.FunctionDeclaration>;
typeIdMap: Map<string, string>;
overrideDisallowSuperfluousObjectProperies?: boolean;
}

@@ -17,0 +21,0 @@

@@ -56,3 +56,3 @@ "use strict";

const condition = VisitorUtils.createBinaries(names.map((name) => ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createStringLiteral(name))), ts.SyntaxKind.AmpersandAmpersandToken, ts.createTrue());
return VisitorUtils.createAssertionFunction(condition, { type: 'object-keyof', properties: names }, name);
return VisitorUtils.createAssertionFunction(condition, { type: 'object-keyof', properties: names }, name, visitorContext);
});

@@ -59,0 +59,0 @@ }

@@ -18,6 +18,26 @@ "use strict";

ts.createIf(ts.createBinary(ts.createTypeOf(ts.createIdentifier('global')), ts.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), ts.createStringLiteral('undefined')), ts.createExpressionStatement(ts.createBinary(ts.createIdentifier('nativeDateObject'), ts.createToken(ts.SyntaxKind.EqualsToken), ts.createPropertyAccess(ts.createIdentifier('window'), ts.createIdentifier('Date')))), ts.createExpressionStatement(ts.createBinary(ts.createIdentifier('nativeDateObject'), ts.createToken(ts.SyntaxKind.EqualsToken), ts.createPropertyAccess(ts.createIdentifier('global'), ts.createIdentifier('Date'))))),
ts.createIf(ts.createLogicalNot(ts.createBinary(ts.createIdentifier('object'), ts.createToken(ts.SyntaxKind.InstanceOfKeyword), ts.createIdentifier('nativeDateObject'))), ts.createReturn(VisitorUtils.createErrorObject({ type: 'date' })), ts.createReturn(ts.createNull()))
ts.createIf(ts.createLogicalNot(ts.createBinary(ts.createIdentifier('object'), ts.createToken(ts.SyntaxKind.InstanceOfKeyword), ts.createIdentifier('nativeDateObject'))), ts.createReturn(VisitorUtils.createErrorObject({ type: 'date' }, visitorContext)), ts.createReturn(ts.createNull()))
], true));
});
}
function createRecursiveCall(functionName, functionArgument, pathExpression, visitorContext) {
const errorIdentifier = ts.createIdentifier('error');
const emitDetailedErrors = !!visitorContext.options.emitDetailedErrors;
const statements = [];
if (emitDetailedErrors) {
statements.push(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'push'), undefined, [
VisitorUtils.createBinaries([
pathExpression
], ts.SyntaxKind.PlusToken)
])));
}
statements.push(ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [
ts.createVariableDeclaration(errorIdentifier, undefined, ts.createCall(ts.createIdentifier(functionName), undefined, [functionArgument]))
]));
if (emitDetailedErrors) {
statements.push(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'pop'), undefined, undefined)));
}
statements.push(ts.createIf(errorIdentifier, ts.createReturn(errorIdentifier)));
return statements;
}
function visitTupleObjectType(type, visitorContext) {

@@ -29,3 +49,2 @@ const name = VisitorTypeName.visitType(type, visitorContext, { type: 'type-check' });

: [];
const errorIdentifier = ts.createIdentifier('error');
const maxLength = functionNames.length;

@@ -48,11 +67,4 @@ let minLength = functionNames.length;

ts.createBinary(ts.createNumericLiteral(maxLength.toString()), ts.SyntaxKind.LessThanToken, ts.createPropertyAccess(VisitorUtils.objectIdentifier, 'length'))
], ts.SyntaxKind.BarBarToken), ts.createReturn(VisitorUtils.createErrorObject({ type: 'tuple', minLength, maxLength }))),
...functionNames.map((functionName, index) => ts.createBlock([
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'push'), undefined, [ts.createStringLiteral(`[${index}]`)])),
ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [
ts.createVariableDeclaration(errorIdentifier, undefined, ts.createCall(ts.createIdentifier(functionName), undefined, [ts.createElementAccess(VisitorUtils.objectIdentifier, index)]))
]),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'pop'), undefined, undefined)),
ts.createIf(errorIdentifier, ts.createReturn(errorIdentifier))
])),
], ts.SyntaxKind.BarBarToken), ts.createReturn(VisitorUtils.createErrorObject({ type: 'tuple', minLength, maxLength }, visitorContext))),
...functionNames.map((functionName, index) => ts.createBlock(createRecursiveCall(functionName, ts.createElementAccess(VisitorUtils.objectIdentifier, index), ts.createStringLiteral(`[${index}]`), visitorContext))),
ts.createReturn(ts.createNull())

@@ -71,3 +83,2 @@ ]));

const indexIdentifier = ts.createIdentifier('i');
const errorIdentifier = ts.createIdentifier('error');
return ts.createFunctionDeclaration(undefined, undefined, undefined, name, undefined, [

@@ -77,17 +88,8 @@ ts.createParameter(undefined, undefined, undefined, VisitorUtils.objectIdentifier, undefined, undefined, undefined)

VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext),
ts.createIf(ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(ts.createIdentifier('Array'), 'isArray'), undefined, [VisitorUtils.objectIdentifier])), ts.createReturn(VisitorUtils.createErrorObject({ type: 'array' }))),
ts.createFor(ts.createVariableDeclarationList([ts.createVariableDeclaration(indexIdentifier, undefined, ts.createNumericLiteral('0'))], ts.NodeFlags.Let), ts.createBinary(indexIdentifier, ts.SyntaxKind.LessThanToken, ts.createPropertyAccess(VisitorUtils.objectIdentifier, 'length')), ts.createPostfixIncrement(indexIdentifier), ts.createBlock([
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'push'), undefined, [
VisitorUtils.createBinaries([
ts.createStringLiteral('['),
indexIdentifier,
ts.createStringLiteral(']')
], ts.SyntaxKind.PlusToken)
])),
ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [
ts.createVariableDeclaration(errorIdentifier, undefined, ts.createCall(ts.createIdentifier(functionName), undefined, [ts.createElementAccess(VisitorUtils.objectIdentifier, indexIdentifier)]))
]),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'pop'), undefined, undefined)),
ts.createIf(errorIdentifier, ts.createReturn(errorIdentifier))
])),
ts.createIf(ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(ts.createIdentifier('Array'), 'isArray'), undefined, [VisitorUtils.objectIdentifier])), ts.createReturn(VisitorUtils.createErrorObject({ type: 'array' }, visitorContext))),
ts.createFor(ts.createVariableDeclarationList([ts.createVariableDeclaration(indexIdentifier, undefined, ts.createNumericLiteral('0'))], ts.NodeFlags.Let), ts.createBinary(indexIdentifier, ts.SyntaxKind.LessThanToken, ts.createPropertyAccess(VisitorUtils.objectIdentifier, 'length')), ts.createPostfixIncrement(indexIdentifier), ts.createBlock(createRecursiveCall(functionName, ts.createElementAccess(VisitorUtils.objectIdentifier, indexIdentifier), VisitorUtils.createBinaries([
ts.createStringLiteral('['),
indexIdentifier,
ts.createStringLiteral(']')
], ts.SyntaxKind.PlusToken), visitorContext))),
ts.createReturn(ts.createNull())

@@ -104,3 +106,2 @@ ]));

const keyIdentifier = ts.createIdentifier('key');
const errorIdentifier = ts.createIdentifier('error');
return ts.createFunctionDeclaration(undefined, undefined, undefined, name, undefined, [

@@ -114,3 +115,3 @@ ts.createParameter(undefined, undefined, undefined, VisitorUtils.objectIdentifier, undefined, undefined, undefined)

ts.createCall(ts.createPropertyAccess(ts.createIdentifier('Array'), 'isArray'), undefined, [VisitorUtils.objectIdentifier])
], ts.SyntaxKind.BarBarToken), ts.createReturn(VisitorUtils.createErrorObject({ type: 'object' }))),
], ts.SyntaxKind.BarBarToken), ts.createReturn(VisitorUtils.createErrorObject({ type: 'object' }, visitorContext))),
...propertyInfos.map((propertyInfo) => {

@@ -128,27 +129,13 @@ if (propertyInfo.isSymbol) {

return ts.createBlock([
ts.createIf(ts.createBinary(ts.createStringLiteral(propertyInfo.name), ts.SyntaxKind.InKeyword, VisitorUtils.objectIdentifier), ts.createBlock([
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'push'), undefined, [ts.createStringLiteral(propertyInfo.name)])),
ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [
ts.createVariableDeclaration(errorIdentifier, undefined, ts.createCall(ts.createIdentifier(functionName), undefined, [ts.createElementAccess(VisitorUtils.objectIdentifier, ts.createStringLiteral(propertyInfo.name))]))
]),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'pop'), undefined, undefined)),
ts.createIf(errorIdentifier, ts.createReturn(errorIdentifier))
]), propertyInfo.optional
ts.createIf(ts.createBinary(ts.createStringLiteral(propertyInfo.name), ts.SyntaxKind.InKeyword, VisitorUtils.objectIdentifier), ts.createBlock(createRecursiveCall(functionName, ts.createElementAccess(VisitorUtils.objectIdentifier, ts.createStringLiteral(propertyInfo.name)), ts.createStringLiteral(propertyInfo.name), visitorContext)), propertyInfo.optional
? undefined
: ts.createReturn(VisitorUtils.createErrorObject({ type: 'missing-property', property: propertyInfo.name })))
: ts.createReturn(VisitorUtils.createErrorObject({ type: 'missing-property', property: propertyInfo.name }, visitorContext)))
]);
}),
...(visitorContext.options.disallowSuperfluousObjectProperties && stringIndexFunctionName === undefined
? [VisitorUtils.createSuperfluousPropertiesLoop(propertyInfos.map((propertyInfo) => propertyInfo.name))]
? [VisitorUtils.createSuperfluousPropertiesLoop(propertyInfos.map((propertyInfo) => propertyInfo.name), visitorContext)]
: []),
...(stringIndexFunctionName
? [
ts.createForOf(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(keyIdentifier, undefined, undefined)], ts.NodeFlags.Const), ts.createCall(ts.createPropertyAccess(ts.createIdentifier('Object'), 'keys'), undefined, [VisitorUtils.objectIdentifier]), ts.createBlock([
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'push'), undefined, [keyIdentifier])),
ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ConstKeyword)], [
ts.createVariableDeclaration(errorIdentifier, undefined, ts.createCall(ts.createIdentifier(stringIndexFunctionName), undefined, [ts.createElementAccess(VisitorUtils.objectIdentifier, keyIdentifier)]))
]),
ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(VisitorUtils.pathIdentifier, 'pop'), undefined, undefined)),
ts.createIf(errorIdentifier, ts.createReturn(errorIdentifier))
]))
ts.createForOf(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(keyIdentifier, undefined, undefined)], ts.NodeFlags.Const), ts.createCall(ts.createPropertyAccess(ts.createIdentifier('Object'), 'keys'), undefined, [VisitorUtils.objectIdentifier]), ts.createBlock(createRecursiveCall(stringIndexFunctionName, ts.createElementAccess(VisitorUtils.objectIdentifier, keyIdentifier), keyIdentifier, visitorContext)))
]

@@ -245,3 +232,3 @@ : []),

return VisitorUtils.setFunctionIfNotExists(name, visitorContext, () => {
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createStringLiteral(value)), { type: 'string-literal', value }, name, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createStringLiteral(value)), { type: 'string-literal', value }, name, visitorContext, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
});

@@ -253,3 +240,3 @@ }

return VisitorUtils.setFunctionIfNotExists(name, visitorContext, () => {
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createNumericLiteral(value.toString())), { type: 'number-literal', value }, name, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createNumericLiteral(value.toString())), { type: 'number-literal', value }, name, visitorContext, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
});

@@ -262,2 +249,7 @@ }

function visitUnionOrIntersectionType(type, visitorContext) {
let disallowSuperfluousPropertyCheck = visitorContext.options.disallowSuperfluousObjectProperties;
if (visitorContext.overrideDisallowSuperfluousObjectProperies) {
visitorContext.overrideDisallowSuperfluousObjectProperies = false;
disallowSuperfluousPropertyCheck = false;
}
const typeUnion = type;

@@ -275,8 +267,8 @@ if (tsutils.isUnionType(typeUnion)) {

return VisitorUtils.setFunctionIfNotExists(name, visitorContext, () => {
const functionNames = intersectionType.types.map((type) => visitType(type, Object.assign(Object.assign({}, visitorContext), { options: Object.assign(Object.assign({}, visitorContext.options), { disallowSuperfluousObjectProperties: false }) })));
if (visitorContext.options.disallowSuperfluousObjectProperties) {
const functionNames = intersectionType.types.map((type) => visitType(type, Object.assign(Object.assign({}, visitorContext), { overrideDisallowSuperfluousObjectProperies: true })));
if (disallowSuperfluousPropertyCheck) {
// Check object keys at intersection type level. https://github.com/woutervh-/typescript-is/issues/21
const keys = VisitorIsStringKeyof.visitType(type, visitorContext);
if (keys instanceof Set) {
const loop = VisitorUtils.createSuperfluousPropertiesLoop(utils_1.sliceSet(keys));
const loop = VisitorUtils.createSuperfluousPropertiesLoop(utils_1.sliceSet(keys), visitorContext);
return VisitorUtils.createConjunctionFunction(functionNames, name, [loop]);

@@ -295,3 +287,3 @@ }

return VisitorUtils.setFunctionIfNotExists(name, visitorContext, () => {
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createTrue()), { type: 'boolean-literal', value: true }, name, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createTrue()), { type: 'boolean-literal', value: true }, name, visitorContext, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
});

@@ -302,3 +294,3 @@ }

return VisitorUtils.setFunctionIfNotExists(name, visitorContext, () => {
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createFalse()), { type: 'boolean-literal', value: false }, name, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
return VisitorUtils.createAssertionFunction(ts.createStrictInequality(VisitorUtils.objectIdentifier, ts.createFalse()), { type: 'boolean-literal', value: false }, name, visitorContext, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
});

@@ -323,3 +315,3 @@ }

const condition = VisitorUtils.createBinaries(conditions, ts.SyntaxKind.AmpersandAmpersandToken);
return VisitorUtils.createAssertionFunction(ts.createLogicalNot(condition), { type: 'non-primitive' }, name, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
return VisitorUtils.createAssertionFunction(ts.createLogicalNot(condition), { type: 'non-primitive' }, name, visitorContext, VisitorUtils.createStrictNullCheckStatement(VisitorUtils.objectIdentifier, visitorContext));
});

@@ -376,3 +368,3 @@ }

value: typePairs
});
}, visitorContext);
return VisitorUtils.setFunctionIfNotExists(name, visitorContext, () => ts.factory.createFunctionDeclaration(undefined, undefined, undefined, name, undefined, [

@@ -379,0 +371,0 @@ ts.factory.createParameterDeclaration(undefined, undefined, undefined, VisitorUtils.objectIdentifier, undefined, ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), undefined)

@@ -25,6 +25,15 @@ "use strict";

}
function visitRegularObjectType(type) {
const id = type.id;
return `_${id}`;
function getTypeIndexById(type, { typeIdMap }) {
const id = type.id.toString();
let index = typeIdMap.get(id);
if (index === undefined) {
index = typeIdMap.size.toString();
typeIdMap.set(id, index);
}
return index;
}
function visitRegularObjectType(type, visitorContext) {
const index = getTypeIndexById(type, visitorContext);
return `_${index}`;
}
function visitTypeReference(type, visitorContext, mode) {

@@ -58,3 +67,3 @@ const mapping = VisitorUtils.getTypeReferenceMapping(type, visitorContext);

else {
return visitRegularObjectType(type);
return visitRegularObjectType(type, visitorContext);
}

@@ -83,3 +92,3 @@ }

let name;
const id = type.id;
const index = getTypeIndexById(type, visitorContext);
if ((ts.TypeFlags.Any & type.flags) !== 0) {

@@ -113,3 +122,3 @@ name = VisitorUtils.getAnyFunction(visitorContext);

else if ((ts.TypeFlags.BooleanLiteral & type.flags) !== 0) {
name = `_${id}`;
name = `_${index}`;
}

@@ -126,3 +135,3 @@ else if (tsutils.isTypeReference(type) && visitorContext.previousTypeReference !== type) {

else if (tsutils.isLiteralType(type)) {
name = `_${id}`;
name = `_${index}`;
}

@@ -133,3 +142,3 @@ else if (tsutils.isUnionOrIntersectionType(type)) {

else if ((ts.TypeFlags.NonPrimitive & type.flags) !== 0) {
name = `_${id}`;
name = `_${index}`;
}

@@ -143,3 +152,3 @@ else if ((ts.TypeFlags.Index & type.flags) !== 0) {

else if ((ts.TypeFlags.TemplateLiteral & type.flags) !== 0) {
name = `_${id}`;
name = `_${index}`;
}

@@ -162,3 +171,4 @@ else {

const resolvedType = VisitorUtils.getResolvedTypeParameter(typeArgument, visitorContext) || typeArgument;
name += `_${resolvedType.id}`;
const resolvedTypeIndex = getTypeIndexById(resolvedType, visitorContext);
name += `_${resolvedTypeIndex}`;
}

@@ -165,0 +175,0 @@ }

@@ -42,7 +42,7 @@ import * as ts from 'typescript';

export declare function createStrictNullCheckStatement(identifier: ts.Identifier, visitorContext: VisitorContext): ts.EmptyStatement | ts.IfStatement;
export declare function createAssertionFunction(failureCondition: ts.Expression, expected: Reason, functionName: string, ...otherStatements: ts.Statement[]): ts.FunctionDeclaration;
export declare function createSuperfluousPropertiesLoop(propertyNames: string[]): ts.ForOfStatement;
export declare function createAssertionFunction(failureCondition: ts.Expression, expected: Reason, functionName: string, visitorContext: VisitorContext, ...otherStatements: ts.Statement[]): ts.FunctionDeclaration;
export declare function createSuperfluousPropertiesLoop(propertyNames: string[], visitorContext: VisitorContext): ts.ForOfStatement;
export declare function isBigIntType(type: ts.Type): number | false;
export declare function createErrorObject(reason: Reason): ts.Expression;
export declare function createErrorObject(reason: Reason, visitorContext: VisitorContext): ts.Expression;
export declare function getIntrinsicName(type: ts.Type): string | undefined;
export {};

@@ -174,3 +174,3 @@ "use strict";

return setFunctionIfNotExists(name, visitorContext, () => {
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('function')), { type: 'function' }, name, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('function')), { type: 'function' }, name, visitorContext, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
});

@@ -182,3 +182,3 @@ }

return setFunctionIfNotExists(name, visitorContext, () => {
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('string')), { type: 'string' }, name, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('string')), { type: 'string' }, name, visitorContext, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
});

@@ -190,3 +190,3 @@ }

return setFunctionIfNotExists(name, visitorContext, () => {
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('boolean')), { type: 'boolean' }, name, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('boolean')), { type: 'boolean' }, name, visitorContext, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
});

@@ -198,3 +198,3 @@ }

return setFunctionIfNotExists(name, visitorContext, () => {
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('bigint')), { type: 'big-int' }, name, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('bigint')), { type: 'big-int' }, name, visitorContext, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
});

@@ -206,3 +206,3 @@ }

return setFunctionIfNotExists(name, visitorContext, () => {
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('number')), { type: 'number' }, name, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
return createAssertionFunction(ts.createStrictInequality(ts.createTypeOf(exports.objectIdentifier), ts.createStringLiteral('number')), { type: 'number' }, name, visitorContext, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
});

@@ -214,3 +214,3 @@ }

return setFunctionIfNotExists(name, visitorContext, () => {
return createAssertionFunction(ts.createStrictInequality(exports.objectIdentifier, ts.createIdentifier('undefined')), { type: 'undefined' }, name, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
return createAssertionFunction(ts.createStrictInequality(exports.objectIdentifier, ts.createIdentifier('undefined')), { type: 'undefined' }, name, visitorContext, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
});

@@ -228,3 +228,3 @@ }

}
return createAssertionFunction(ts.createStrictInequality(exports.objectIdentifier, ts.createNull()), { type: 'null' }, name, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
return createAssertionFunction(ts.createStrictInequality(exports.objectIdentifier, ts.createNull()), { type: 'null' }, name, visitorContext, createStrictNullCheckStatement(exports.objectIdentifier, visitorContext));
});

@@ -239,3 +239,3 @@ }

], undefined, ts.createBlock([
ts.createReturn(createErrorObject({ type: 'never' }))
ts.createReturn(createErrorObject({ type: 'never' }, visitorContext))
]));

@@ -323,3 +323,3 @@ });

])),
ts.createReturn(createErrorObject({ type: 'union' }))
ts.createReturn(createErrorObject({ type: 'union' }, visitorContext))
]));

@@ -344,3 +344,3 @@ }

exports.createStrictNullCheckStatement = createStrictNullCheckStatement;
function createAssertionFunction(failureCondition, expected, functionName, ...otherStatements) {
function createAssertionFunction(failureCondition, expected, functionName, visitorContext, ...otherStatements) {
return ts.createFunctionDeclaration(undefined, undefined, undefined, functionName, undefined, [

@@ -350,9 +350,9 @@ ts.createParameter(undefined, undefined, undefined, exports.objectIdentifier, undefined, undefined, undefined)

...otherStatements,
ts.createIf(failureCondition, ts.createReturn(createErrorObject(expected)), ts.createReturn(ts.createNull()))
ts.createIf(failureCondition, ts.createReturn(createErrorObject(expected, visitorContext)), ts.createReturn(ts.createNull()))
]));
}
exports.createAssertionFunction = createAssertionFunction;
function createSuperfluousPropertiesLoop(propertyNames) {
function createSuperfluousPropertiesLoop(propertyNames, visitorContext) {
return ts.createForOf(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(keyIdentifier, undefined, undefined)], ts.NodeFlags.Const), ts.createCall(ts.createPropertyAccess(ts.createIdentifier('Object'), 'keys'), undefined, [exports.objectIdentifier]), ts.createBlock([
ts.createIf(createBinaries(propertyNames.map((propertyName) => ts.createStrictInequality(keyIdentifier, ts.createStringLiteral(propertyName))), ts.SyntaxKind.AmpersandAmpersandToken, ts.createTrue()), ts.createReturn(createErrorObject({ type: 'superfluous-property' })))
ts.createIf(createBinaries(propertyNames.map((propertyName) => ts.createStrictInequality(keyIdentifier, ts.createStringLiteral(propertyName))), ts.SyntaxKind.AmpersandAmpersandToken, ts.createTrue()), ts.createReturn(createErrorObject({ type: 'superfluous-property' }, visitorContext)))
]));

@@ -387,3 +387,6 @@ }

}
function createErrorObject(reason) {
function createErrorObject(reason, visitorContext) {
if (visitorContext.options.emitDetailedErrors === false) {
return ts.createObjectLiteral([]);
}
return ts.createObjectLiteral([

@@ -390,0 +393,0 @@ ts.createPropertyAssignment('message', createErrorMessage(reason)),

{
"name": "typescript-is",
"version": "0.18.3",
"version": "0.19.0",
"engines": {

@@ -37,3 +37,2 @@ "node": ">=6.14.4"

"nested-error-stacks": "^2",
"reflect-metadata": ">=0.1.12",
"tsutils": "^3.17.1"

@@ -40,0 +39,0 @@ },

@@ -140,2 +140,4 @@ # typescript-is

| `disallowSuperfluousObjectProperties` | Boolean (default: `false`). If `true`, objects are checked for having superfluous properties and will cause the validation to fail if they do. If `false`, no check for superfluous properties is made. |
| `transformNonNullExpressions` | Boolean (default: `false`). If `true`, non-null expressions (eg. `foo!.bar`) are checked to not be `null` or `undefined` |
| `emitDetailedErrors` | Boolean or `auto` (default: `auto`). The generated validation functions can return detailed error messages, pointing out where and why validation failed. These messages are used by `assertType<T>()`, but are ignored by `is<T>()`. If `false`, validation functions return empty error messages, decreasing code size. `auto` will generate detailed error messages for assertions, but not for type checks. `true` will always generate detailed error messages, matching the behaviour of version 0.18.3 and older. |

@@ -154,3 +156,5 @@ If you are using `ttypescript`, you can include the options in your `tsconfig.json`:

"functionBehavior": "ignore",
"disallowSuperfluousObjectProperties": true
"disallowSuperfluousObjectProperties": true,
"transformNonNullExpressions": true,
"emitDetailedErrors": "auto"
}

@@ -262,2 +266,70 @@ ]

### async and `Promise` returning methods
`AssertType` can also work correctly with `async` methods, returning promise rejected with `TypeGuardError`
To enable this functionality, you need to emit decorators metadata for your TypeScript project.
```json
{
"compilerOptions": {
"emitDecoratorMetadata": true
}
}
```
Then `AssertType` will work with async methods and `Promise` returning methods automatically.
```typescript
import { ValidateClass, AssertType } from 'typescript-is';
@ValidateClass()
class A {
async method(@AssertType({ async: true }) value: number) {
// You can safely use value as a number
return value;
}
methodPromise(@AssertType({ async: true }) value: number): Promise<number> {
// You can safely use value as a number
return Promise.resolve(value);
}
}
new A().method(42).then(value => value === 42 /* true */);
new A().method('42' as any).catch(error => {
// error will be of TypeGuardError type
})
new A().methodPromise('42' as any).catch(error => {
// error will be of TypeGuardError type
})
```
If you want to throw synchronously for some reason, you can override the behaviour using with `@AssertType({ async: false })`:
```typescript
import { ValidateClass, AssertType } from 'typescript-is';
@ValidateClass()
class A {
async method(@AssertType({ async: false }) value: number) {
// You can safely use value as a number
return value;
}
}
new A().method(42).then(value => value === 42 /* true */);
new A().method('42' as any); // will throw error
```
If you cannot or don't want to enable decorators metadata, you still make AssertType reject with promise using `@AssertType({ async: true })`
```typescript
import { ValidateClass, AssertType } from 'typescript-is';
@ValidateClass()
class A {
async method(@AssertType({ async: true }) value: number) {
// You can safely use value as a number
return value;
}
}
```
## Strict equality (`equals`, `createEquals`, `assertEquals`, `createAssertEquals`)

@@ -264,0 +336,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚑️ by Socket Inc