Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Ján Naništa committed Mar 30, 2021
1 parent a9e2c6d commit 7175cee
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 10 deletions.
36 changes: 29 additions & 7 deletions src/transformer/typeDescriptor/typeDescriptorGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as assert from './utils/assert';
import { Logger } from '../utils/logger';
import { TypeDescriptor } from '../types';
import { TypeDescriptor, TypeName } from '../types';
import { TypeDescriptorGenerator, TypeDescriptorGeneratorCallback, TypeNameResolver } from '../types';
import { functionTypeWarning, promiseTypeWarning } from './utils/messages';
import { getDOMElementClassName } from './utils/getDOMElementClassName';
import { getLibraryTypeDescriptorName } from './utils/getLibraryTypeDescriptorName';
import { getPropertyTypeDescriptors } from './utils/getPropertyTypeDescriptors';
import ts from 'typescript';
import { typeFlags } from '../utils/debug';
import ts from 'typescript';

/**
* A factory for TypeDescriptorGenerator functions.
Expand Down Expand Up @@ -96,7 +96,7 @@ export const createTypeDescriptorGenerator = (program: ts.Program, logger: Logge
if (assert.isNever(type)) return { _type: 'never' };

// For the checks below we need access to the TypeNode for this type
const typeNode = typeChecker.typeToTypeNode(type, scope);
const typeNode = typeChecker.typeToTypeNode(type, scope, undefined);
const typeName = typeChecker.typeToString(type, scope);

// True
Expand All @@ -119,8 +119,6 @@ export const createTypeDescriptorGenerator = (program: ts.Program, logger: Logge
});
}



// Literal types
if (assert.isLiteral(type)) {
if (type.value === undefined) {
Expand Down Expand Up @@ -157,11 +155,35 @@ export const createTypeDescriptorGenerator = (program: ts.Program, logger: Logge
return { _type: 'keyword', value: 'object' };
}

if (typeNode && ts.isTupleTypeNode(typeNode)) {
const typeElementNodes = typeNode.elements;
const typeArguments = (type as ts.TupleType).typeArguments || [];
debugger;

// const types = typeNode.elements.map<TypeName | [TypeName]>(unitType => {
// // return resolve(scope, unitType.type)
// });

return (resolve: TypeNameResolver) => ({
_type: 'tuple',
types: typeArguments.map((type, index) => {
const typeElementNode = typeElementNodes[index];
if (ts.isRestTypeNode(typeElementNode)) {
console.warn('rest type node', typeName, index);

return [resolve(scope, type)];
}

return resolve(scope, type);
}),
});
}

// Tuple
if (assert.isTuple(type, typeNode)) {
logger.debug('Tuple');

const typeArguments = type.typeArguments || [];
typeArguments.forEach((arg) => console.log('type', typeFlags(arg)));
debugger;

return (resolve: TypeNameResolver) => ({
_type: 'tuple',
Expand Down
3 changes: 1 addition & 2 deletions src/transformer/typeGuard/utils/codeGenerators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,11 @@ export const createTupleTypeGuard = (
length: number,
createElementCheck: (value: ts.Expression, index: number) => ts.Expression,
): ts.Expression => {
const arrayLengthCheck = ts.createStrictEquality(ts.createPropertyAccess(value, 'length'), ts.createLiteral(length));
const elementChecks = Array.from({ length }).map((_, index) =>
createElementCheck(ts.createElementAccess(value, index), index),
);

return createLogicalAndChain(createIsArray(value), arrayLengthCheck, ...elementChecks);
return createLogicalAndChain(createIsArray(value), ...elementChecks);
};

const createIsNotNumeric = (value: ts.Expression): ts.Expression =>
Expand Down
2 changes: 1 addition & 1 deletion src/transformer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export interface ArrayTypeDescriptor {

export interface TupleTypeDescriptor {
_type: 'tuple';
types: TypeName[];
types: Array<TypeName | [TypeName]>;
}

export interface PromiseTypeDescriptor {
Expand Down
2 changes: 2 additions & 0 deletions test/scripts/versions.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
4.2.3
4.1.5
4.0.7
3.9.2
3.8.2
Expand Down
1 change: 1 addition & 0 deletions test/setups/typescript--4.2.3/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../jest.config');
14 changes: 14 additions & 0 deletions test/setups/typescript--4.2.3/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "@ts-type-checked/test--typescript--4.2.3",
"version": "0.0.1",
"private": true,
"peerDependencies": {
"typescript": ">=4.2.3"
},
"dependencies": {
"ts-type-checked": "file:../../../dist"
},
"devDependencies": {
"ts-reflection": "^0.3.0"
}
}
45 changes: 45 additions & 0 deletions test/setups/typescript--4.2.3/tests/tuples.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'jest';

import { assert, notAnArray, notAnEmptyArray, notOfType, numeric, oneOf, primitive } from '../../../utils/utils.v2';
import { isA, typeCheckFor } from 'ts-type-checked';
import fc from 'fast-check';

describe('Tuples', () => {
// test('With optional elements', () => {
// type TypeReference1 = [string, number, boolean?];

// const validArbitrary: fc.Arbitrary<TypeReference1> = oneOf<TypeReference1>(
// fc.tuple(fc.string(), numeric()),
// fc.tuple(fc.string(), numeric(), fc.boolean()),
// );
// const invalidArbitrary = oneOf<unknown>(
// primitive(),
// fc.anything().filter(notAnArray),
// fc.array(numeric()),
// fc.tuple(fc.string(), fc.string()),
// fc.tuple(numeric(), numeric()),
// fc.tuple(fc.string(), numeric(), fc.anything().filter(notOfType('boolean'))),
// fc.constantFrom(["string", "string"], [6, 6], ["string", 7, 7]),
// );

// assert(validArbitrary, invalidArbitrary, [typeCheckFor<TypeReference1>(), (value) => isA<TypeReference1>(value)]);
// });

test('With rest elements at the beginning', () => {
type TypeReference1 = [...boolean[], string];

const validArbitrary: fc.Arbitrary<TypeReference1> = oneOf<TypeReference1>(
fc.tuple(fc.string()),
fc.array(fc.boolean()).chain((booleans) => fc.string().map((string) => [...booleans, string])),
);
const invalidArbitrary = oneOf<unknown>(
primitive(),
fc
.array(fc.anything().filter(notOfType('boolean')).filter(notAnEmptyArray))
.chain((values) => fc.string().map((string) => [...values, string])),
fc.constantFrom([6, 'string']),
);

assert(validArbitrary, invalidArbitrary, [typeCheckFor<TypeReference1>(), (value) => isA<TypeReference1>(value)]);
});
});
7 changes: 7 additions & 0 deletions test/setups/typescript--4.2.3/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"target": "ESNext"
}
}

0 comments on commit 7175cee

Please sign in to comment.