Skip to content

Commit 919a29e

Browse files
authored
Fix camel-casing keys in nested objects when using union with null (#119)
1 parent 2a782c1 commit 919a29e

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

index.d.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import type {CamelCase, PascalCase} from 'type-fest';
33
// eslint-disable-next-line @typescript-eslint/ban-types
44
type EmptyTuple = [];
55

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

89
/**
910
Return a default type if input type is nil.
@@ -38,7 +39,7 @@ type AppendPath<S extends string, Last extends string> = S extends ''
3839
Convert keys of an object to camelcase strings.
3940
*/
4041
export type CamelCaseKeys<
41-
T extends ObjectOptional | readonly any[],
42+
T extends ObjectUnion | readonly any[],
4243
Deep extends boolean = false,
4344
IsPascalCase extends boolean = false,
4445
PreserveConsecutiveUppercase extends boolean = false,
@@ -71,7 +72,7 @@ export type CamelCaseKeys<
7172
]
7273
? T[P]
7374
: [Deep] extends [true]
74-
? T[P] extends ObjectOptional | readonly any[]
75+
? T[P] extends ObjectUnion | readonly any[]
7576
? CamelCaseKeys<
7677
T[P],
7778
Deep,

index.test-d.ts

+13
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,16 @@ function camelcaseKeysPascalCase<
471471

472472
expectType<{fooBar: {hogeHoge: string}}>(camelcaseKeysDeep({foo_bar: {hoge_hoge: 'hoge_hoge'}}));
473473
expectType<{FooBar: string}>(camelcaseKeysPascalCase({foo_bar: 'foo_bar'}));
474+
475+
// Test for union type
476+
// eslint-disable-next-line @typescript-eslint/ban-types
477+
const objectCamelcased: CamelCaseKeys<{foo_bar: {foo_prop: string} | null}, true>
478+
= camelcaseKeys({foo_bar: {foo_prop: 'foo_props'}}, {deep: true});
479+
// eslint-disable-next-line @typescript-eslint/ban-types
480+
const nullCamelcased: CamelCaseKeys<{foo_bar: {foo_prop: string} | null}, true>
481+
= camelcaseKeys({foo_bar: null}, {deep: true});
482+
483+
// eslint-disable-next-line @typescript-eslint/ban-types
484+
expectType<{fooBar: {fooProp: string} | null}>(objectCamelcased);
485+
// eslint-disable-next-line @typescript-eslint/ban-types
486+
expectType<{fooBar: {fooProp: string} | null}>(nullCamelcased);

0 commit comments

Comments
 (0)