knex/test-tsd/tsd-tests2.test-d.ts

553 lines
15 KiB
TypeScript
Raw Permalink Normal View History

import { knex, Knex } from '../types';
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<T1 extends T2, T2> {
_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<User>, Knex>;
type _T2 = ExtendsWitness<Knex<User, Partial<User>[]>, Knex>;
type _T3 = ExtendsWitness<Knex.Where<User, Partial<User>[]>, Knex.Where>;
type _T4 = ExtendsWitness<Knex.Where<User, number>, Knex.Where>;
type _T5 = ExtendsWitness<
Knex.QueryInterface<User, Partial<User[]>>,
Knex.QueryInterface
>;
type _T6 = ExtendsWitness<Knex.QueryBuilder<User, User[]>, Knex.QueryBuilder>;
type _T7 = ExtendsWitness<
Knex.QueryBuilder<User, User[]>,
Knex.QueryBuilder<any, any[]>
>;
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 '../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<Array<Pick<User, 'name'> & { identifier: number }>>(
await knexInstance
.select(knexInstance.ref('id').as('identifier'), 'name')
.from('users_inferred')
);
expectType<Array<Pick<User, 'name'> & { identifier: number }>>(
await knexInstance
.select(knexInstance.ref('id').as('identifier'), 'name')
.from('users_composite')
);
const r10 = await knexInstance
.select(
knexInstance.ref('id').as('identifier'),
'name',
knexInstance.ref('age').as('yearsSinceBirth')
)
.from<User>('users');
type _TR10 = ExtendsWitness<
(typeof r10)[0],
{ identifier: number; name: string; yearsSinceBirth: number }
>;
// FixMe
// expectType<Array<{ identifier: number; name: string; yearsSinceBirth: number }>>(r10);
expectType<
Array<{ identifier: number; name: string; yearsSinceBirth: number }>
>(
await knexInstance
.select(
knexInstance.ref('id').as('identifier'),
'name',
knexInstance.ref('age').as('yearsSinceBirth')
)
.from('users_inferred')
);
expectType<
Array<{ identifier: number; name: string; yearsSinceBirth: number }>
>(
await knexInstance
.select(
knexInstance.ref('id').as('identifier'),
'name',
knexInstance.ref('age').as('yearsSinceBirth')
)
.from('users_composite')
);
expectType<Array<{ id: number; age: any }>>(
await knexInstance<User>('users').select(knexInstance.ref('id'), {
age: 'users.age',
})
);
expectType<Array<{ id: number; age: any }>>(
await knexInstance('users_inferred').select(knexInstance.ref('id'), {
age: 'users.age',
})
);
expectType<Array<{ id: number; age: any }>>(
await knexInstance('users_composite').select(knexInstance.ref('id'), {
age: 'users.age',
})
);
expectType<{ id: number; age: any } | undefined>(
await knexInstance<User>('users')
.select(knexInstance.ref('id'), { age: 'users.age' })
.first()
);
expectType<{ id: number; age: any } | undefined>(
await knexInstance('users_inferred')
.select(knexInstance.ref('id'), { age: 'users.age' })
.first()
);
expectType<{ id: number; age: any } | undefined>(
await knexInstance('users_composite')
.select(knexInstance.ref('id'), { age: 'users.age' })
.first()
);
expectType<Array<{ identifier: number; username: string }>>(
(await knexInstance<User>('users').select('id', 'name')).map((u) => ({
identifier: u.id,
username: u.name,
}))
);
expectType<Array<{ identifier: number; username: string }>>(
(await knexInstance('users_inferred').select('id', 'name')).map((u) => ({
identifier: u.id,
username: u.name,
}))
);
expectType<Array<{ identifier: number; username: string }>>(
(await knexInstance('users_composite').select('id', 'name')).map((u) => ({
identifier: u.id,
username: u.name,
}))
);
expectType<Array<{ identifier: number; username: string }>>(
(await knexInstance.select('id', 'name').from<User>('users')).map((u) => ({
identifier: u.id,
username: u.name,
}))
);
expectType<Array<{ identifier: number; username: string }>>(
(await knexInstance.select('id', 'name').from('users_inferred')).map(
(u) => ({
identifier: u.id,
username: u.name,
})
)
);
expectType<Array<{ identifier: number; username: string }>>(
(await knexInstance.select('id', 'name').from('users_composite')).map(
(u) => ({
identifier: u.id,
username: u.name,
})
)
);
// This one is not strongly typed because `.from('users')` doesnt reference a typed table
// so the user type is `any`.
expectType<Array<{ identifier: any; username: any }>>(
(await knexInstance.select('id', 'name').from('users')).map((u) => ({
identifier: u.id,
username: u.name,
}))
);
expectType<number>(
(await knexInstance.select('id', 'name', 'age').from<User>('users')).reduce(
(maxAge: number, user) => (user.age > maxAge ? user.age : maxAge),
0
)
);
expectType<number>(
(
await knexInstance.select('id', 'name', 'age').from('users_inferred')
).reduce(
(maxAge: number, user) => (user.age > maxAge ? user.age : maxAge),
0
)
);
expectType<number>(
(
await knexInstance.select('id', 'name', 'age').from('users_composite')
).reduce(
(maxAge: number, user) => (user.age > maxAge ? user.age : maxAge),
0
)
);
expectType<any>(
(
await knexInstance('table')
.select('key', 'value')
.where({ namespace: 'foo' })
).reduce(
(aggr, { value, key }) => ({
...aggr,
[key]: value > 10 ? (aggr[key] || 0) + 1 : aggr[key],
}),
{} as any
)
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance<User>('users').select(['id', 'age'])
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance('users_inferred').select(['id', 'age'])
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance('users_composite').select(['id', 'age'])
);
expectType<Pick<User, 'id' | 'age'> | undefined>(
await knexInstance<User>('users').select(['id', 'age']).first()
);
expectType<Pick<User, 'id' | 'age'> | undefined>(
await knexInstance('users_inferred').select(['id', 'age']).first()
);
expectType<Pick<User, 'id' | 'age'> | undefined>(
await knexInstance('users_composite').select(['id', 'age']).first()
);
// Not strongly typed since `'users'` is not referencing a typed table
expectType<any[]>(await knexInstance<User>('users').select('users.id'));
expectType<Array<Pick<User, 'name'>>>(
await knexInstance<User>('users')
.select(['id', 'age'])
.clearSelect()
.select(['name'])
);
expectType<Array<Pick<User, 'name'>>>(
await knexInstance('users_inferred')
.select(['id', 'age'])
.clearSelect()
.select(['name'])
);
expectType<Array<Pick<User, 'name'>>>(
await knexInstance('users_composite')
.select(['id', 'age'])
.clearSelect()
.select(['name'])
);
expectType<Array<Pick<User, 'name' | 'departmentId'>>>(
await knexInstance<User>('users')
.select('id')
.select('age')
.clearSelect()
.select('name')
.select('departmentId')
);
expectType<Array<Pick<User, 'name' | 'departmentId'>>>(
await knexInstance('users_inferred')
.select('id')
.select('age')
.clearSelect()
.select('name')
.select('departmentId')
);
expectType<Array<Pick<User, 'name' | 'departmentId'>>>(
await knexInstance('users_composite')
.select('id')
.select('age')
.clearSelect()
.select('name')
.select('departmentId')
);
expectType<Array<Pick<User, 'name' | 'departmentId'>>>(
await knexInstance
.select('id')
.select('age')
.clearSelect()
.select('name')
.select('departmentId')
.from<User>('users')
);
expectType<Array<Pick<User, 'name' | 'departmentId'>>>(
await knexInstance
.select('id')
.select('age')
.clearSelect()
.select('name')
.select('departmentId')
.from('users_inferred')
);
expectType<Array<Pick<User, 'name' | 'departmentId'>>>(
await knexInstance
.select('id')
.select('age')
.clearSelect()
.select('name')
.select('departmentId')
.from('users_composite')
);
// Not strongly typed since `'users'` is not referencing a typed table
expectType<any[]>(
await knexInstance<User>('users').select('users.id').select('age')
);
// Not strongly typed since `'departments'` is not referencing a typed table
expectType<any[]>(
await knexInstance<User>('users').select('id').from('departments')
);
// This one is typed because `'departments'` references a typed table
expectType<Array<Pick<Department, 'id'>>>(
await knexInstance<User>('users')
.select('id')
.from<Department>('departments')
);
expectType<Array<Pick<Department, 'id'>>>(
await knexInstance('users_inferred')
.select('id')
.from('departments_inferred')
);
expectType<Array<Pick<Department, 'id'>>>(
await knexInstance('users_composite')
.select('id')
.from('departments_composite')
);
// Not strongly typed since `'users'` is not referencing a typed table
expectType<any[]>(await knexInstance.select('id').from('users'));
expectType<Array<Pick<User, 'id'>>>(
await knexInstance.select('id').from<User>('users')
);
expectType<Array<Pick<User, 'id'>>>(
await knexInstance.select('id').from('users_inferred')
);
expectType<Array<Pick<User, 'id'>>>(
await knexInstance.select('id').from('users_composite')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance.select('id', 'age').from<User>('users')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance.select('id', 'age').from('users_inferred')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance.select('id', 'age').from('users_composite')
);
expectType<Array<Pick<User, 'id'>>>(
await knexInstance.from<User>('users').select('id')
);
expectType<Array<Pick<User, 'id'>>>(
await knexInstance.from('users_inferred').select('id')
);
expectType<Array<Pick<User, 'id'>>>(
await knexInstance.from('users_composite').select('id')
);
// Not strongly typed since `'users'` is not referencing a typed table
expectType<any[]>(await knexInstance.from<User>('users').select('users.id'));
// Force-casting the return to a narrower type (less common usage)
expectType<Array<Pick<User, 'id'>>>(
await knexInstance
.from<User>('users')
.select<Pick<User, 'id'>[]>('users.id')
);
// Not strongly typed since `'users'` is not referencing a typed table
expectType<any[]>(
await knexInstance.column('id', 'age').select().from('users')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance.column('id', 'age').select().from<User>('users')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance.column('id', 'age').select().from('users_inferred')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance.column('id', 'age').select().from('users_composite')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance<User>('users').column('id', 'age').select()
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance('users_inferred').column('id', 'age').select()
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance('users_composite').column('id', 'age').select()
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance<User>('users').column('id', 'age')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance('users_inferred').column('id', 'age')
);
expectType<Array<Pick<User, 'id' | 'age'>>>(
await knexInstance('users_composite').column('id', 'age')
);
// Not strongly typed since `'users'` is not referencing a typed table
expectType<any[]>(await knexInstance('users').distinct('name', 'age'));
expectType<Array<Pick<User, 'name' | 'age'>>>(
await knexInstance<User>('users').distinct('name', 'age')
);
expectType<Array<Pick<User, 'name' | 'age'>>>(
await knexInstance('users_inferred').distinct('name', 'age')
);
expectType<Array<Pick<User, 'name' | 'age'>>>(
await knexInstance('users_composite').distinct('name', 'age')
);
expectType<
Array<Pick<User, 'name' | 'id' | 'age' | 'active' | 'departmentId'>>
>(await knexInstance<User>('users').distinct());
expectType<
Array<Pick<User, 'name' | 'id' | 'age' | 'active' | 'departmentId'>>
>(await knexInstance('users_inferred').distinct());
expectType<
Array<Pick<User, 'name' | 'id' | 'age' | 'active' | 'departmentId'>>
>(await knexInstance('users_composite').distinct());
expectType<Array<User>>(await knexInstance.select('*').from<User>('users'));
expectType<Array<User>>(
await knexInstance.select('*').from('users_inferred')
);
expectType<Array<User>>(
await knexInstance.select('*').from('users_composite')
);
};
class ExcelClient extends knex.Client {}