Skip to content
This repository has been archived by the owner on Feb 20, 2020. It is now read-only.

Commit

Permalink
fix(sub-type): should transform correctly (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
ikatyang authored Aug 12, 2017
1 parent 2b6a644 commit a64b8f9
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 45 deletions.
3 changes: 2 additions & 1 deletion src/__tests__/__snapshots__/parse.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ declare const v_object: {
readonly [index: number]: any;
};
declare const v_sub_1: X[any][\\"abc\\"][123];
declare const v_sub_2: A.B.C[X[any]][any][any];
declare const v_sub_2: A.B.C[X[any]][any];
declare const v_tuple: [string, number];
declare const v_typeof_1: typeof X;
declare const v_typeof_2: typeof X.Y.Z;
Expand Down Expand Up @@ -186,5 +186,6 @@ type TP<T> = T | string;
type adjust = <T, U>(fn: (v: T) => U, index: number, array: T[]) => (T | U)[];
declare function x<T>(v: T): T;
import xyz = require(\\"xyz\\");
type X = A[B[C]];
"
`;
2 changes: 2 additions & 0 deletions src/__tests__/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ type adjust = <T, U>(fn: (v: T) => U, index: number, array: T[]) => (T | U)[];
declare function x<T>(v: T): T;
import xyz = require('xyz');
type X = A[B[C]];
`;

it('should return correctly', () => {
Expand Down
13 changes: 4 additions & 9 deletions src/parsers/indexed-access-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@ import { create_sub_type, ISubType } from '../types/sub-type';

export const parse_indexed_access_type = (
node: ts.IndexedAccessTypeNode,
): ISubType => {
const types = [node.objectType, node.indexType];
while (types[types.length - 1].kind === ts.SyntaxKind.IndexedAccessType) {
const last_type = types[types.length - 1] as ts.IndexedAccessTypeNode;
types.push(last_type.indexType);
}
return create_sub_type({
types: types.map(parse_native),
): ISubType =>
create_sub_type({
object: parse_native(node.objectType),
index: parse_native(node.indexType),
});
};
4 changes: 3 additions & 1 deletion src/types/__tests__/__snapshots__/sub-type.ts.snap
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should return correctly 1`] = `"any[string][number]"`;
exports[`should return correctly with object 1`] = `"string[any]"`;

exports[`should return correctly with object and index 1`] = `"any[string][number]"`;
10 changes: 4 additions & 6 deletions src/types/__tests__/mapped-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,10 @@ it('should return correctly with parameter, optional, readonly, type', () => {
optional: true,
readonly: true,
type: create_sub_type({
types: [
in_type,
create_general_type({
name: parameter.name,
}),
],
object: in_type,
index: create_general_type({
name: parameter.name,
}),
}),
}),
),
Expand Down
22 changes: 15 additions & 7 deletions src/types/__tests__/sub-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,38 @@ import { any_type, number_type, string_type } from '../../constants';
import { emit } from '../../emit';
import { create_sub_type, is_sub_type } from '../sub-type';

it('should return correctly', () => {
it('should return correctly with object', () => {
expect(
emit(
create_sub_type({
types: [any_type, string_type, number_type],
object: string_type,
}),
),
).toMatchSnapshot();
});

it('should throw error with types (length < 2)', () => {
expect(() =>
it('should return correctly with object and index', () => {
expect(
emit(
create_sub_type({
types: [],
object: create_sub_type({
object: any_type,
index: string_type,
}),
index: number_type,
}),
),
).toThrowError();
).toMatchSnapshot();
});

describe('is_sub_type', () => {
it('should return correctly', () => {
const element = create_sub_type({
types: [any_type, string_type, number_type],
object: create_sub_type({
object: any_type,
index: string_type,
}),
index: number_type,
});
expect(is_sub_type(element)).toBe(true);
});
Expand Down
29 changes: 8 additions & 21 deletions src/types/sub-type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ts from 'typescript';
import { IType } from '../collections';
import { ElementKind } from '../constants';
import { any_type, ElementKind } from '../constants';
import {
create_element,
is_element,
Expand All @@ -10,7 +10,8 @@ import {
import { transform } from '../transform';

export interface ISubTypeOptions extends IElementOptions {
types: IType[];
object: IType;
index?: IType;
}

export interface ISubType
Expand All @@ -28,22 +29,8 @@ export const is_sub_type = (value: any): value is ISubTypeOptions =>
/**
* @hidden
*/
export const transform_sub_type = (
element: ISubType,
path: IElement<any>[],
) => {
const minimum_length_of_types = 2;
if (element.types.length < minimum_length_of_types) {
throw new Error(
`sub_type.types.length should >= ${minimum_length_of_types}`,
);
}
const types = element.types.map(type => transform(type, path) as ts.TypeNode);
return types
.slice(minimum_length_of_types)
.reduce(
(parent_type, sub_type) =>
ts.createIndexedAccessTypeNode(parent_type, sub_type),
ts.createIndexedAccessTypeNode(types[0], types[1]),
);
};
export const transform_sub_type = (element: ISubType, path: IElement<any>[]) =>
ts.createIndexedAccessTypeNode(
transform(element.object, path) as ts.TypeNode,
transform(element.index || any_type, path) as ts.TypeNode,
);

0 comments on commit a64b8f9

Please sign in to comment.