Repository: sindresorhus/type-fest (TypeScript)

Issue:
CamelCasedObjectDeep breaks tuple-types into array-types
Code says more than 1000 words :)

```ts
import { CamelCasedPropertiesDeep } from "type-fest";

type Object = {
    tuple_property: [number, number]
}

// type CamelCasedObject = {
//    tupleProperty: [number, number]; // <-- working
// }
type CamelCasedObject = CamelCasedProperties<Object>

// type CamelCasedObjectDeep = {
//    tupleProperty: number[]; // <-- broken
// }
type CamelCasedObjectDeep = CamelCasedPropertiesDeep<Object>
```


Discussion:

Patch:
diff --git a/source/camel-cased-properties-deep.d.ts b/source/camel-cased-properties-deep.d.ts
index b44482be6..8ba3491d7 100644
--- a/source/camel-cased-properties-deep.d.ts
+++ b/source/camel-cased-properties-deep.d.ts
@@ -1,4 +1,5 @@
 import type {CamelCase, CamelCaseOptions} from './camel-case';
+import type {UnknownArray} from './unknown-array';
 
 /**
 Convert object properties to camel case recursively.
@@ -44,11 +45,43 @@ const result: CamelCasedPropertiesDeep<UserWithFriends> = {
 @category Template literal
 @category Object
 */
-export type CamelCasedPropertiesDeep<Value, Options extends CamelCaseOptions = {preserveConsecutiveUppercase: true}> = Value extends Function
+export type CamelCasedPropertiesDeep<
+	Value,
+	Options extends CamelCaseOptions = {preserveConsecutiveUppercase: true},
+> = Value extends Function
 	? Value
-	: Value extends Array<infer U>
-		? Array<CamelCasedPropertiesDeep<U, Options>>
+	: Value extends UnknownArray
+		? CamelCasedPropertiesArrayDeep<Value>
 		: Value extends Set<infer U>
-			? Set<CamelCasedPropertiesDeep<U, Options>> : {
-				[K in keyof Value as CamelCase<K, Options>]: CamelCasedPropertiesDeep<Value[K], Options>;
+			? Set<CamelCasedPropertiesDeep<U, Options>>
+			: {
+				[K in keyof Value as CamelCase<K, Options>]: CamelCasedPropertiesDeep<
+				Value[K],
+				Options
+				>;
 			};
+
+// This is a copy of DelimiterCasedPropertiesArrayDeep (see: delimiter-cased-properties-deep.d.ts).
+// These types should be kept in sync.
+type CamelCasedPropertiesArrayDeep<Value extends UnknownArray> =
+	Value extends []
+		? []
+		: // Tailing spread array
+		Value extends [infer U, ...infer V]
+			? [CamelCasedPropertiesDeep<U>, ...CamelCasedPropertiesDeep<V>]
+			: Value extends readonly [infer U, ...infer V]
+				? readonly [CamelCasedPropertiesDeep<U>, ...CamelCasedPropertiesDeep<V>]
+				: // Leading spread array
+				Value extends readonly [...infer U, infer V]
+					? [...CamelCasedPropertiesDeep<U>, CamelCasedPropertiesDeep<V>]
+					: Value extends readonly [...infer U, infer V]
+						? readonly [
+							...CamelCasedPropertiesDeep<U>,
+							CamelCasedPropertiesDeep<V>,
+						]
+						: // Array
+						Value extends Array<infer U>
+							? Array<CamelCasedPropertiesDeep<U>>
+							: Value extends ReadonlyArray<infer U>
+								? ReadonlyArray<CamelCasedPropertiesDeep<U>>
+								: never;
diff --git a/source/delimiter-cased-properties-deep.d.ts b/source/delimiter-cased-properties-deep.d.ts
index c6077c339..b91ff25eb 100644
--- a/source/delimiter-cased-properties-deep.d.ts
+++ b/source/delimiter-cased-properties-deep.d.ts
@@ -61,6 +61,8 @@ export type DelimiterCasedPropertiesDeep<
 				>]: DelimiterCasedPropertiesDeep<Value[K], Delimiter>;
 			};
 
+// This is a copy of CamelCasedPropertiesArrayDeep (see: camel-cased-properties-deep.d.ts).
+// These types should be kept in sync.
 type DelimiterCasedPropertiesArrayDeep<Value extends UnknownArray, Delimiter extends string> =
 	Value extends []
 		? []


Test patch:
diff --git a/test-d/camel-cased-properties-deep.ts b/test-d/camel-cased-properties-deep.ts
index 5f79ebd2e..83c1a1d4d 100644
--- a/test-d/camel-cased-properties-deep.ts
+++ b/test-d/camel-cased-properties-deep.ts
@@ -19,6 +19,9 @@ expectType<{fooBAR: number; baz: {fooBAR: number; bARFoo: string}}>(baz);
 declare const biz: CamelCasedPropertiesDeep<bazBizDeep, {preserveConsecutiveUppercase: false}>;
 expectType<{fooBar: number; baz: {fooBar: number; barFoo: string}}>(biz);
 
+declare const tuple: CamelCasedPropertiesDeep<{tuple: [number, string, {D: string}]}>;
+expectType<{tuple: [number, string, {d: string}]}>(tuple);
+
 // Verify example
 type User = {
 	UserId: number;