Skip to content

Commit

Permalink
[types] Make Knex's default generic parameter types be assignable to …
Browse files Browse the repository at this point in the history
…knex's

The default generic parameters of `Knex` didn't match the generic parameter types of `knex`. This becomes relevant with TypeScript 4.6 for `k: Knex = knex()` to work.

We can't change `knex`'s declaration from `TResult = unknown[]` to `TResult = Record<string, any>[]` because other types like `DeferredKeySelection.ReplaceBase` specifically look for `unknown`. Instead, this commit changes `Knex` to use `TResult = any[]`.

This works with TypeScript 4.6. Added both tsd and dtslint tests (tsd doesn't support TS 4.6 yet). Also tested this change in a larger codebase and confirmed that nearly all TS 4.6 errors were addressed.
  • Loading branch information
ide committed Feb 12, 2022
1 parent e64e37b commit a3d4df1
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
12 changes: 12 additions & 0 deletions test-tsd/types.test-d.ts
Expand Up @@ -19,6 +19,18 @@ expectType<Knex<any, unknown[]>>(knexCjsImport.knex({}));
expectType<KnexTimeoutError>(new knex.KnexTimeoutError());
expectType<KnexTimeoutError>(new knex.KnexTimeoutError());

// Knex instances need to be assigned first so their generic types aren't inferred
const k1 = knex({});
expectAssignable<Knex>(k1);
const k2 = knexStar.default({});
expectAssignable<Knex>(k2);
const k3 = knexStar.knex({});
expectAssignable<Knex>(k3);
const k4 = knexCjsImport.default({});
expectAssignable<Knex>(k4);
const k5 = knexCjsImport.knex({});
expectAssignable<Knex>(k5);

// eslint-disable-next-line
expectType<any>(knexCjs({}));
// eslint-disable-next-line
Expand Down
2 changes: 1 addition & 1 deletion types/index.d.ts
Expand Up @@ -328,7 +328,7 @@ interface DMLOptions {
includeTriggerModifications?: boolean;
}

export interface Knex<TRecord extends {} = any, TResult = Record<string, any>[]>
export interface Knex<TRecord extends {} = any, TResult = any[]>
extends Knex.QueryInterface<TRecord, TResult>, events.EventEmitter {
<TTable extends Knex.TableNames>(
tableName: TTable,
Expand Down
3 changes: 3 additions & 0 deletions types/test.ts
Expand Up @@ -82,6 +82,9 @@ type _T8 = ExtendsWitness<Knex.QueryBuilder<User, number[]>, Knex.QueryBuilder>;
type _T9 = ExtendsWitness<Knex.QueryBuilder<any, any[]>, Knex.QueryBuilder>;
type _T10 = ExtendsWitness<Knex.QueryBuilder<User, number>, Knex.QueryBuilder>;

// Ensure the return type of knex() is compatible with Knex with default parameters
type _T2_1 = ExtendsWitness<typeof knexInstance, Knex>;

declare module './tables' {
interface Tables {
users_inferred: User;
Expand Down

0 comments on commit a3d4df1

Please sign in to comment.