Skip to content

Commit

Permalink
Fix camel-casing keys in nested objects when using union with null (#119
Browse files Browse the repository at this point in the history
)
  • Loading branch information
yutak23 authored Oct 18, 2023
1 parent 2a782c1 commit 919a29e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
7 changes: 4 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import type {CamelCase, PascalCase} from 'type-fest';
// eslint-disable-next-line @typescript-eslint/ban-types
type EmptyTuple = [];

type ObjectOptional = Record<string, unknown> | undefined;
// Allow union with, for example, `undefined` and `null`.
type ObjectUnion = Record<string, unknown> | unknown;

/**
Return a default type if input type is nil.
Expand Down Expand Up @@ -38,7 +39,7 @@ type AppendPath<S extends string, Last extends string> = S extends ''
Convert keys of an object to camelcase strings.
*/
export type CamelCaseKeys<
T extends ObjectOptional | readonly any[],
T extends ObjectUnion | readonly any[],
Deep extends boolean = false,
IsPascalCase extends boolean = false,
PreserveConsecutiveUppercase extends boolean = false,
Expand Down Expand Up @@ -71,7 +72,7 @@ export type CamelCaseKeys<
]
? T[P]
: [Deep] extends [true]
? T[P] extends ObjectOptional | readonly any[]
? T[P] extends ObjectUnion | readonly any[]
? CamelCaseKeys<
T[P],
Deep,
Expand Down
13 changes: 13 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,16 @@ function camelcaseKeysPascalCase<

expectType<{fooBar: {hogeHoge: string}}>(camelcaseKeysDeep({foo_bar: {hoge_hoge: 'hoge_hoge'}}));
expectType<{FooBar: string}>(camelcaseKeysPascalCase({foo_bar: 'foo_bar'}));

// Test for union type
// eslint-disable-next-line @typescript-eslint/ban-types
const objectCamelcased: CamelCaseKeys<{foo_bar: {foo_prop: string} | null}, true>
= camelcaseKeys({foo_bar: {foo_prop: 'foo_props'}}, {deep: true});
// eslint-disable-next-line @typescript-eslint/ban-types
const nullCamelcased: CamelCaseKeys<{foo_bar: {foo_prop: string} | null}, true>
= camelcaseKeys({foo_bar: null}, {deep: true});

// eslint-disable-next-line @typescript-eslint/ban-types
expectType<{fooBar: {fooProp: string} | null}>(objectCamelcased);
// eslint-disable-next-line @typescript-eslint/ban-types
expectType<{fooBar: {fooProp: string} | null}>(nullCamelcased);

0 comments on commit 919a29e

Please sign in to comment.