Improved PaginateConfig
and Column
autocompletion (#931)
This commit is contained in:
parent
dfecad17f6
commit
acd158961f
@ -1,36 +1,72 @@
|
|||||||
import { SelectQueryBuilder } from 'typeorm'
|
import { SelectQueryBuilder } from 'typeorm'
|
||||||
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata'
|
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Joins 2 keys as `K`, `K.P`, `K.(P` or `K.P)`
|
||||||
|
* The parenthesis notation is included for embedded columns
|
||||||
|
*/
|
||||||
type Join<K, P> = K extends string
|
type Join<K, P> = K extends string
|
||||||
? P extends string
|
? P extends string
|
||||||
? `${K}${'' extends P ? '' : '.'}${P | `(${P}` | `${P})`}`
|
? `${K}${'' extends P ? '' : '.'}${P | `(${P}` | `${P})`}`
|
||||||
: never
|
: never
|
||||||
: never
|
: never
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the previous number between 0 and 10. Examples:
|
||||||
|
* Prev[3] = 2
|
||||||
|
* Prev[0] = never.
|
||||||
|
* Prev[20] = 0
|
||||||
|
*/
|
||||||
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]]
|
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]]
|
||||||
|
|
||||||
// unwrap Promise type
|
/**
|
||||||
|
* Unwrap Promise<T> to T
|
||||||
|
*/
|
||||||
type UnwrapPromise<T> = T extends Promise<infer U> ? UnwrapPromise<U> : T
|
type UnwrapPromise<T> = T extends Promise<infer U> ? UnwrapPromise<U> : T
|
||||||
|
|
||||||
// Unwrap Array type
|
/**
|
||||||
|
* Unwrap Array<T> to T
|
||||||
|
*/
|
||||||
type UnwrapArray<T> = T extends Array<infer U> ? UnwrapArray<U> : T
|
type UnwrapArray<T> = T extends Array<infer U> ? UnwrapArray<U> : T
|
||||||
|
|
||||||
// TODO: puts some comments here, in this ternary of doom
|
/**
|
||||||
|
* Find all the dotted path properties for a given column.
|
||||||
|
*
|
||||||
|
* T: The column
|
||||||
|
* D: max depth
|
||||||
|
*/
|
||||||
|
// v Have we reached max depth?
|
||||||
export type Column<T, D extends number = 2> = [D] extends [never]
|
export type Column<T, D extends number = 2> = [D] extends [never]
|
||||||
? never
|
? // yes, stop recursing
|
||||||
: T extends Record<string, any>
|
never
|
||||||
|
: // Are we extending something with keys?
|
||||||
|
T extends Record<string, any>
|
||||||
? {
|
? {
|
||||||
|
// For every keyof T, find all possible properties as a string union
|
||||||
[K in keyof T]-?: K extends string
|
[K in keyof T]-?: K extends string
|
||||||
? T[K] extends Date
|
? // Is it string or number (includes enums)?
|
||||||
? `${K}`
|
T[K] extends string | number
|
||||||
: T[K] extends Array<infer U>
|
? // yes, add just the key
|
||||||
? `${K}` | Join<K, Column<UnwrapArray<U>, Prev[D]>>
|
`${K}`
|
||||||
: T[K] extends Promise<infer U>
|
: // Is it a Date?
|
||||||
? U extends Array<infer V>
|
T[K] extends Date
|
||||||
|
? // yes, add just the key
|
||||||
|
`${K}`
|
||||||
|
: // no, is it an array?
|
||||||
|
T[K] extends Array<infer U>
|
||||||
|
? // yes, unwrap it, and recurse deeper
|
||||||
|
`${K}` | Join<K, Column<UnwrapArray<U>, Prev[D]>>
|
||||||
|
: // no, is it a promise?
|
||||||
|
T[K] extends Promise<infer U>
|
||||||
|
? // yes, try to infer its return type and recurse
|
||||||
|
U extends Array<infer V>
|
||||||
? `${K}` | Join<K, Column<UnwrapArray<V>, Prev[D]>>
|
? `${K}` | Join<K, Column<UnwrapArray<V>, Prev[D]>>
|
||||||
: `${K}` | Join<K, Column<UnwrapPromise<U>, Prev[D]>>
|
: `${K}` | Join<K, Column<UnwrapPromise<U>, Prev[D]>>
|
||||||
: `${K}` | Join<K, Column<T[K], Prev[D]>>
|
: // no, we have no more special cases, so treat it as an
|
||||||
|
// object and recurse deeper on its keys
|
||||||
|
`${K}` | Join<K, Column<T[K], Prev[D]>>
|
||||||
: never
|
: never
|
||||||
|
// Join all the string unions of each keyof T into a single string union
|
||||||
}[keyof T]
|
}[keyof T]
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
|
@ -70,13 +70,17 @@ export interface PaginateConfig<T> {
|
|||||||
sortableColumns: Column<T>[]
|
sortableColumns: Column<T>[]
|
||||||
nullSort?: 'first' | 'last'
|
nullSort?: 'first' | 'last'
|
||||||
searchableColumns?: Column<T>[]
|
searchableColumns?: Column<T>[]
|
||||||
select?: Column<T>[] | string[]
|
// see https://github.com/microsoft/TypeScript/issues/29729 for (string & {})
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
select?: (Column<T> | (string & {}))[]
|
||||||
maxLimit?: number
|
maxLimit?: number
|
||||||
defaultSortBy?: SortBy<T>
|
defaultSortBy?: SortBy<T>
|
||||||
defaultLimit?: number
|
defaultLimit?: number
|
||||||
where?: FindOptionsWhere<T> | FindOptionsWhere<T>[]
|
where?: FindOptionsWhere<T> | FindOptionsWhere<T>[]
|
||||||
filterableColumns?: {
|
filterableColumns?: {
|
||||||
[key in Column<T> | string]?: (FilterOperator | FilterSuffix)[] | true
|
// see https://github.com/microsoft/TypeScript/issues/29729 for (string & {})
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
[key in Column<T> | (string & {})]?: (FilterOperator | FilterSuffix)[] | true
|
||||||
}
|
}
|
||||||
loadEagerRelations?: boolean
|
loadEagerRelations?: boolean
|
||||||
withDeleted?: boolean
|
withDeleted?: boolean
|
||||||
|
Loading…
Reference in New Issue
Block a user