import { knex, Knex } from '../types'; import { PassThrough } from 'stream'; import { expectType } from 'tsd'; const clientConfig = { client: 'sqlite3', connection: { filename: './mydb.sqlite', }, }; const knexInstance = knex(clientConfig); const knex2 = knex({ ...clientConfig, log: { debug(msg: string) { // }, }, pool: { log: (msg: string, level: string) => { // }, }, }); knexInstance.initialize(); knexInstance.initialize({}); interface User { id: number; age: number; name: string; active: boolean; departmentId: number; } interface Department { id: number; departmentName: string; } interface Article { id: number; subject: string; body?: string; authorId?: string; } interface Ticket { name: string; from: string; to: string; at: Date; } // Interface to witness type compatibility interface ExtendsWitness { _t: T1; } // Ensure that Knex type with parameters is compatible with Knex with default parameters // // This ensures that a value of Parameterized Knex can always be passed to a function that // consumes unparameterized Knex. type _T1 = ExtendsWitness, Knex>; type _T2 = ExtendsWitness[]>, Knex>; type _T3 = ExtendsWitness[]>, Knex.Where>; type _T4 = ExtendsWitness, Knex.Where>; type _T5 = ExtendsWitness< Knex.QueryInterface>, Knex.QueryInterface >; type _T6 = ExtendsWitness, Knex.QueryBuilder>; type _T7 = ExtendsWitness< Knex.QueryBuilder, Knex.QueryBuilder >; type _T8 = ExtendsWitness, Knex.QueryBuilder>; type _T9 = ExtendsWitness, Knex.QueryBuilder>; type _T10 = ExtendsWitness, Knex.QueryBuilder>; // Ensure the return type of knex() is compatible with Knex with default parameters type _T2_1 = ExtendsWitness; declare module '../types/tables' { interface Tables { users_inferred: User; departments_inferred: Department; articles_inferred: Article; users_composite: Knex.CompositeTableType< User, { insert: 'insert' }, { update: 'update' } >; departments_composite: Knex.CompositeTableType< Department, { insert: 'insert' }, { update: 'update' } >; articles_composite: Knex.CompositeTableType< Article, { insert: 'insert' }, { update: 'update' } >; } } const main = async () => { expectType(await knexInstance.raw('select * from users')); expectType(await knexInstance.raw('select * from users')); expectType( await knexInstance.raw( 'select * from users where id in ?', knexInstance('contacts').select('name') ) ); expectType( await knexInstance.raw( 'select * from users where id in ?', knexInstance('contacts').select('name') ) ); expectType( await knexInstance.raw( 'select * from users where departmentId in ?', knexInstance('departments').select('id') ) ); expectType( await knexInstance.raw( 'select * from users where departmentId in ? & active in ?', [knexInstance('departments').select('name'), [true, false]] ) ); expectType( await knexInstance.raw( 'select * from articles where authorId = ?', [null] ) ); expectType>( knexInstance('users').select('*').stream() ); expectType( knexInstance('users').select('*').stream().pipe(new PassThrough()) ); expectType( await knexInstance('user').where('name', ['a', 'b', 'c']) ); expectType( await knexInstance('users_inferred').where('name', ['a', 'b', 'c']) ); expectType( await knexInstance('users_composite').where('name', ['a', 'b', 'c']) ); expectType( await knexInstance('user').whereRaw('name = ?', 'L') ); expectType( await knexInstance('users_inferred').whereRaw('name = ?', 'L') ); expectType( await knexInstance('users_composite').whereRaw('name = ?', 'L') ); expectType( await knexInstance('user').whereRaw('name = ?', 'L').clearWhere() ); expectType( await knexInstance('users_inferred').whereRaw('name = ?', 'L').clearWhere() ); expectType( await knexInstance('users_composite').whereRaw('name = ?', 'L').clearWhere() ); expectType( await knexInstance('user').whereBetween('id', [1, 2]) ); expectType( await knexInstance('users_inferred').whereBetween('id', [1, 2]) ); expectType( await knexInstance('users_composite').whereBetween('id', [1, 2]) ); const range = [1, 2] as const; expectType( await knexInstance('user').whereBetween('id', range) ); expectType( await knexInstance('users_inferred').whereBetween('id', range) ); expectType( await knexInstance('users_composite').whereBetween('id', range) ); const r3 = await knexInstance('users').select(knexInstance.ref('id')); expectType<{ id: number }[]>(r3); expectType<{ id: number }[]>( await knexInstance('users_inferred').select(knexInstance.ref('id')) ); expectType<{ id: number }[]>( await knexInstance('users_composite').select(knexInstance.ref('id')) ); const r4 = await knexInstance('users').select( knexInstance.ref('id'), 'name' ); type _TR4 = ExtendsWitness<(typeof r4)[0], Pick>; // FixMe // expectType<(Pick)[]>(r4); expectType[]>( await knexInstance('users_inferred').select(knexInstance.ref('id'), 'name') ); expectType[]>( await knexInstance('users_composite').select(knexInstance.ref('id'), 'name') ); const r5 = await knexInstance('users').select( knexInstance.ref('id').as('identifier'), 'name' ); type _TR5 = ExtendsWitness< (typeof r5)[0], { identifier: number; name: string } >; // FixMe // expectType<{ identifier: number; name: string }[]>(r5); expectType<{ identifier: number; name: string }[]>( await knexInstance('users_inferred').select( knexInstance.ref('id').as('identifier'), 'name' ) ); expectType<{ identifier: number; name: string }[]>( await knexInstance('users_composite').select( knexInstance.ref('id').as('identifier'), 'name' ) ); const r6 = await knexInstance('users').select( knexInstance.ref('id').as('identifier'), 'name', knexInstance.ref('age').as('yearsSinceBirth') ); type _TR6 = ExtendsWitness< (typeof r6)[0], { identifier: number; name: string; yearsSinceBirth: number } >; // FixMe //expectType< // { identifier: number; name: string; yearsSinceBirth: number }[] //>(r6); expectType<{ identifier: number; name: string; yearsSinceBirth: number }[]>( await knexInstance('users_inferred').select( knexInstance.ref('id').as('identifier'), 'name', knexInstance.ref('age').as('yearsSinceBirth') ) ); expectType<{ identifier: number; name: string; yearsSinceBirth: number }[]>( await knexInstance('users_composite').select( knexInstance.ref('id').as('identifier'), 'name', knexInstance.ref('age').as('yearsSinceBirth') ) ); const r7 = await knexInstance .select(knexInstance.ref('id')) .from('users'); type _TR7 = ExtendsWitness<(typeof r7)[0], Pick>; expectType<{ id: number }[]>(r7); expectType<{ id: number }[]>( await knexInstance.select(knexInstance.ref('id')).from('users_inferred') ); expectType<{ id: number }[]>( await knexInstance.select(knexInstance.ref('id')).from('users_composite') ); const r8 = await knexInstance .select(knexInstance.ref('id'), 'name') .from('users'); type _TR8 = ExtendsWitness<(typeof r8)[0], Pick>; // FixMe // expectType<(Pick)[]>(r8); expectType[]>( await knexInstance .select(knexInstance.ref('id'), 'name') .from('users_inferred') ); expectType[]>( await knexInstance .select(knexInstance.ref('id'), 'name') .from('users_composite') ); const r9 = await knexInstance .select(knexInstance.ref('id').as('identifier'), 'name') .from('users'); type _TR9 = ExtendsWitness< (typeof r9)[0], { identifier: number; name: string } >; // FixMe // expectType<{ identifier: number; name: string }[]>(r9); }; class ExcelClient extends knex.Client {}