From 0d5fc691c1a4a8d1e6ad4e345ca187b9089dfc7a Mon Sep 17 00:00:00 2001 From: Masahiko Shin Date: Tue, 21 Jun 2022 17:30:12 +0900 Subject: [PATCH] Improve type inference. Type inferences for some kind of values(functions, records, promises,.etc) are not correct when deep option is enabled. It is because CamelCaseKeys type accepts Record and then accepts some object-like types such as functions or promises. --- index.d.ts | 38 +++++++++++++++++++++----------------- index.test-d.ts | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/index.d.ts b/index.d.ts index e1e9416..3ed41af 100644 --- a/index.d.ts +++ b/index.d.ts @@ -45,13 +45,15 @@ export type CamelCaseKeys< > = T extends readonly any[] // Handle arrays or tuples. ? { - [P in keyof T]: CamelCaseKeys< - T[P], - Deep, - IsPascalCase, - Exclude, - StopPaths - >; + [P in keyof T]: Record extends CamelCaseKeys + ? T[P] + : CamelCaseKeys< + T[P], + Deep, + IsPascalCase, + Exclude, + StopPaths + >; } : T extends Record // Handle objects. @@ -64,16 +66,18 @@ export type CamelCaseKeys< true, ] ? T[P] - : [Deep] extends [true] - ? CamelCaseKeys< - T[P], - Deep, - IsPascalCase, - Exclude, - StopPaths, - AppendPath - > - : T[P]; + : Record extends CamelCaseKeys + ? T[P] + : [Deep] extends [true] + ? CamelCaseKeys< + T[P], + Deep, + IsPascalCase, + Exclude, + StopPaths, + AppendPath + > + : T[P]; } // Return anything else as-is. : T; diff --git a/index.test-d.ts b/index.test-d.ts index f2b2f99..2ee6076 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -350,3 +350,27 @@ expectNotType( exclude, }), ); + +expectType<{ + funcFoo: () => 'foo'; + recordBar: {foo: string}; + promiseBaz: Promise; +}>(camelcaseKeys({ + func_foo: () => 'foo', + record_bar: {foo: 'bar'}, + promise_baz: new Promise(resolve => { + resolve(true); + }), + })); + +expectType<[ + () => 'foo', + {foo: string}, + Promise, +]>(camelcaseKeys([ + () => 'foo', + {foo: 'bar'}, + new Promise(resolve => { + resolve(true); + }), + ]));