Skip to content

Commit

Permalink
fix: handle object conversion of optional arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
RossWilliams committed Jul 2, 2021
1 parent f0c2d0f commit ce40b27
Show file tree
Hide file tree
Showing 8 changed files with 657 additions and 496 deletions.
1 change: 1 addition & 0 deletions .gitattributes

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions .github/workflows/stale.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .projen/tasks.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 34 additions & 21 deletions src/caseConvert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,18 @@ export type ObjectToCamel<T extends object | undefined | null> =
? undefined
: T extends null
? null
: T extends Array<infer ArrayType>
? ArrayType extends object
? Array<ObjectToPascal<ArrayType>>
: Array<ArrayType>
: {
[K in keyof T as ToCamel<K>]: T[K] extends Array<unknown>
? T[K] extends Array<infer ArrayType>
? ArrayType extends object
? Array<ObjectToCamel<ArrayType>>
: T[K]
: never
[K in keyof T as ToCamel<K>]: T[K] extends
| Array<infer ArrayType>
| undefined
| null
? ArrayType extends object
? Array<ObjectToCamel<ArrayType>>
: Array<ArrayType>
: T[K] extends object | undefined | null
? ObjectToCamel<T[K]>
: T[K];
Expand All @@ -131,13 +136,18 @@ export type ObjectToPascal<T extends object | undefined | null> =
? undefined
: T extends null
? null
: T extends Array<infer ArrayType>
? ArrayType extends object
? Array<ObjectToPascal<ArrayType>>
: Array<ArrayType>
: {
[K in keyof T as ToPascal<K>]: T[K] extends Array<unknown>
? T[K] extends Array<infer ArrayType>
? ArrayType extends object
? Array<ObjectToPascal<ArrayType>>
: T[K]
: never
[K in keyof T as ToPascal<K>]: T[K] extends
| Array<infer ArrayType>
| undefined
| null
? ArrayType extends object
? Array<ObjectToPascal<ArrayType>>
: Array<ArrayType>
: T[K] extends object | undefined | null
? ObjectToPascal<T[K]>
: T[K];
Expand Down Expand Up @@ -190,18 +200,21 @@ export type ObjectToSnake<T extends object | undefined | null> =
? undefined
: T extends null
? null
: T extends Array<infer ArrayType>
? ArrayType extends object
? Array<ObjectToSnake<ArrayType>>
: Array<ArrayType>
: {
[K in keyof T as ToSnake<K>]: T[K] extends Array<unknown>
? T[K] extends Array<infer ArrayType>
? ArrayType extends object
? Array<ObjectToSnake<ArrayType>>
: T[K]
: never
[K in keyof T as ToSnake<K>]: T[K] extends
| Array<infer ArrayType>
| undefined
| null
? ArrayType extends object
? Array<ObjectToSnake<ArrayType>>
: Array<ArrayType>
: T[K] extends object | undefined | null
? ObjectToSnake<T[K]>
: // Exclude<T[K], undefined> extends object
// ? ObjectToSnake<Exclude<T[K], undefined>>
T[K];
: T[K];
};

type CapitalLetters =
Expand Down
115 changes: 115 additions & 0 deletions test/caseConvert.bugs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {
ObjectToCamel,
ObjectToPascal,
ObjectToSnake,
} from '../src/caseConvert';

describe('bug fixes', () => {
it('#50 - Does not handle an array of objects correctly', () => {
interface MyObject {
index: number;
value?: string;
}

interface MyObjectWithArray {
object_array: MyObject[];
}

type CamelCaseConvertedObjectWithArray = ObjectToCamel<MyObjectWithArray>;

const camelRequest: CamelCaseConvertedObjectWithArray = {
objectArray: [
{
index: 0,
value: 'abc',
},
],
};

expect(camelRequest.objectArray?.length).toEqual(1);

camelRequest.objectArray?.forEach((value) => {
expect(value.index).toEqual(0);
});

type PascalCaseConvertedObjectWithArray = ObjectToPascal<MyObjectWithArray>;
const pascalRequest: PascalCaseConvertedObjectWithArray = {
ObjectArray: [
{
Index: 0,
Value: 'abc',
},
],
};

expect(pascalRequest.ObjectArray?.length).toEqual(1);

pascalRequest.ObjectArray?.forEach((value) => {
expect(value.Index).toEqual(0);
});

interface MyPascalObjectWithArray {
ObjectArray?: {
Index: number;
Value?: string;
}[];
}

type SnakeCaseConvertedObjectWithArray =
ObjectToSnake<MyPascalObjectWithArray>;

const snakeRequest: SnakeCaseConvertedObjectWithArray = {
object_array: [
{
index: 0,
value: 'abc',
},
],
};

expect(snakeRequest.object_array?.length).toEqual(1);

snakeRequest.object_array?.forEach((value) => {
expect(value.index).toEqual(0);
});
});
});

// Bug #50
interface ArrayTypes {
arrayOfString: string[];
optionalArrayOfString?: string[];
arrayOfArrayOfString: string[][];
optionalArrayOfArrayofString1?: string[][];
arrayOfOptionalArrayOfString: Array<string[] | undefined>;
}

type SnakeArrayTypes = ObjectToSnake<ArrayTypes>;

const _snakeArrays1: SnakeArrayTypes = {
array_of_string: ['a'],
array_of_array_of_string: [['a']],
array_of_optional_array_of_string: [['a']],
optional_array_of_string: ['a'],
};

const _snakeArrays2: SnakeArrayTypes = {
array_of_string: ['a'],
array_of_array_of_string: [['a']],
array_of_optional_array_of_string: [undefined],
optional_array_of_string: undefined,
};

const _camelArrays1: ObjectToCamel<ArrayTypes> = {
arrayOfString: ['a'],
arrayOfArrayOfString: [['a']],
arrayOfOptionalArrayOfString: [['a']],
optionalArrayOfString: ['a'],
};

const _camelArrays2: ObjectToCamel<ArrayTypes> = {
arrayOfString: ['a'],
arrayOfArrayOfString: [['a']],
arrayOfOptionalArrayOfString: [undefined],
optionalArrayOfString: undefined,
};
Loading

0 comments on commit ce40b27

Please sign in to comment.