Skip to content

Commit 5c13343

Browse files
committed
Type improvements for selection maps
1 parent b2250ae commit 5c13343

File tree

5 files changed

+88
-21
lines changed

5 files changed

+88
-21
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ This file contains the changes made to the package.
33

44
The sections are in descending order of the change date.
55

6+
## [0.1.7] - 2022-04-27
7+
### Changed
8+
- Type improvements for `selectionMap` option.
9+
610
## [0.1.6] - 2022-04-27
711
### Added
812
- Changelog file.
@@ -17,5 +21,6 @@ object.
1721
The initial version of the package.
1822

1923
[Unreleased]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/compare/v1.0.0...HEAD
24+
[0.1.7]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/compare/0.1.6...0.1.7
2025
[0.1.6]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/compare/0.1.5...0.1.6
2126
[0.1.5]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/releases/tag/0.1.5

src/dynamic-resolvers.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export interface IOnResolvingParams<P extends object = object> {
2727
readonly resolveInfo: GraphQLResolveInfo
2828
}
2929

30-
export interface IOnResolvedParams<R extends object, P extends object = object> extends IOnResolvingParams<P> {
30+
export interface IOnResolvedParams<R = any, P extends object = object> extends IOnResolvingParams<P> {
3131
/**
3232
* The data resolved by the resolver.
3333
*
@@ -43,7 +43,7 @@ export interface IOnResolvedParams<R extends object, P extends object = object>
4343
* @export
4444
* @interface IUseDynamicResolversParams
4545
*/
46-
export interface IUseDynamicResolversParams<R extends object = object, P extends object = object> {
46+
export interface IUseDynamicResolversParams {
4747
/**
4848
* The name of the module that will contain the resolver.
4949
*
@@ -93,7 +93,7 @@ export interface IUseDynamicResolversParams<R extends object = object, P extends
9393
* An event function that will be triggered when the resolver is about to resolve the defined navigation.
9494
*
9595
* @param {IOnResolvingParams<P>} params The parameters.
96-
* @return {(Promise<R | undefined | void> | R | undefined | void)} The
96+
* @return {*} The
9797
* replace value.
9898
*
9999
* If this function returns a value from this event function, then the
@@ -102,13 +102,13 @@ export interface IUseDynamicResolversParams<R extends object = object, P extends
102102
*
103103
* @memberof IUseDynamicResolversParams
104104
*/
105-
onResolving?(params: IOnResolvingParams<P>): Promise<R | undefined | void> | R | undefined | void
105+
onResolving?<P extends object>(params: IOnResolvingParams<P>): any
106106

107107
/**
108108
* An event function that will be triggered when the resolved is resolved the defined navigation.
109109
*
110-
* @param {IOnResolvedParams<R, P>} params The parameters.
111-
* @return {(Promise<R | undefined | void> | undefined | void)} The
110+
* @param {IOnResolvedParams<any, P>} params The parameters.
111+
* @return {*} The
112112
* replace value.
113113
*
114114
* If this function returns a value from this event function, then the
@@ -117,7 +117,7 @@ export interface IUseDynamicResolversParams<R extends object = object, P extends
117117
*
118118
* @memberof IUseDynamicResolversParams
119119
*/
120-
onResolved?(params: IOnResolvedParams<R, P>): Promise<R | undefined | void> | undefined | void
120+
onResolved?<P extends object = object>(params: IOnResolvedParams<any, P>): any
121121
}
122122

123123
export interface IRegisterDynamicResolverParams extends IUseDynamicResolversParams {

src/helpers/extract-grapql-selections.ts

+20-12
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ import { FieldNode, GraphQLResolveInfo, Kind } from 'graphql'
1111
*
1212
* @export
1313
* @interface IGraphQLExtractSelectionMap
14+
* @template T The type of the source.
15+
* @template K The keys included of the source.
1416
*/
15-
export interface IGraphQLExtractSelectionMap {
16-
[ k: string ]: string | ((parentKeys: string[], fieldName: string) => string)
17+
export type IGraphQLExtractSelectionMap<T extends object = object, K extends keyof T = Exclude<ObjectKeys<T>, KeysMatching<T, Date>>> = {
18+
[ k in K ]?: string | ((parentKeys: string[], fieldName: K) => string)
1719
}
1820

19-
export interface IExtractGraphQLSelectionsParams {
21+
interface IExtractGraphQLSelectionsParams<T extends object = object, K extends keyof T = Exclude<ObjectKeys<T>, KeysMatching<T, Date>>> {
2022
/**
2123
* The root node of the GraphQL request.
2224
*
@@ -28,10 +30,10 @@ export interface IExtractGraphQLSelectionsParams {
2830
/**
2931
* The map for renaming the field names to database navigation keys.
3032
*
31-
* @type {IGraphQLExtractSelectionMap}
33+
* @type {IGraphQLExtractSelectionMap<T, K>}
3234
* @memberof IParams
3335
*/
34-
selectionMap?: IGraphQLExtractSelectionMap
36+
selectionMap?: IGraphQLExtractSelectionMap<T, K>
3537

3638
/**
3739
* The name array of the parent fields.
@@ -51,8 +53,10 @@ export interface IExtractGraphQLSelectionsParams {
5153
* extraction.
5254
*
5355
* @return {*} An object of `selected` field names.
56+
* @template T The type of the source.
57+
* @template K The keys included of the source.
5458
*/
55-
export function extractGraphQLSelections(params: IExtractGraphQLSelectionsParams) {
59+
export function extractGraphQLSelections<T extends object = object, K extends keyof T = Exclude<ObjectKeys<T>, KeysMatching<T, Date>>>(params: IExtractGraphQLSelectionsParams<T, K>) {
5660
const { node, parentFieldKeys = [], selectionMap = {} } = params
5761

5862
const { selectionSet } = node
@@ -69,7 +73,7 @@ export function extractGraphQLSelections(params: IExtractGraphQLSelectionsParams
6973
parentFieldKeys: [ ...parentFieldKeys, fieldName ]
7074
})
7175

72-
const mapper = selectionMap[ fieldName ]
76+
const mapper = selectionMap[ fieldName as keyof typeof selectionMap ] as any
7377
let mappedValue: string
7478
if (typeof mapper === 'string') {
7579
mappedValue = mapper
@@ -97,7 +101,7 @@ export function extractGraphQLSelections(params: IExtractGraphQLSelectionsParams
97101
}, {} as Record<string, any>)
98102
}
99103

100-
export interface IExtractGraphQLSelectionPathParams {
104+
interface IExtractGraphQLSelectionPathParams<T extends object = object, K extends keyof T = Exclude<ObjectKeys<T>, KeysMatching<T, Date>>> {
101105
/**
102106
* The initial path of the request.
103107
*
@@ -109,11 +113,11 @@ export interface IExtractGraphQLSelectionPathParams {
109113
/**
110114
* The map for renaming the field names to database navigation keys.
111115
*
112-
* @type {IGraphQLExtractSelectionMap}
116+
* @type {IGraphQLExtractSelectionMap<T, K>}
113117
* @memberof IParams
114118
* @default {}
115119
*/
116-
selectionMap?: IGraphQLExtractSelectionMap
120+
selectionMap?: IGraphQLExtractSelectionMap<T, K>
117121

118122
/**
119123
* The initial root paths.
@@ -131,10 +135,14 @@ export interface IExtractGraphQLSelectionPathParams {
131135
* @export
132136
* @param {IExtractGraphQLSelectionPathParams} params The parameters for
133137
* extraction.
138+
*
134139
* @return {string[]} An array containing field names from the outer level to
135140
* the inner level.
141+
*
142+
* @template T The type of the source.
143+
* @template K The keys included of the source.
136144
*/
137-
export function extractGraphQLSelectionPath(params: IExtractGraphQLSelectionPathParams): string[] {
145+
export function extractGraphQLSelectionPath<T extends object = object, K extends keyof T = Exclude<ObjectKeys<T>, KeysMatching<T, Date>>>(params: IExtractGraphQLSelectionPathParams<T, K>): string[] {
138146
const { path, selectionMap = {}, rootPaths = [] } = params
139147
if (typeof path !== 'object') return rootPaths
140148

@@ -145,7 +153,7 @@ export function extractGraphQLSelectionPath(params: IExtractGraphQLSelectionPath
145153
rootPaths
146154
})
147155

148-
const mapper = selectionMap[ key ]
156+
const mapper = selectionMap[ key as keyof typeof selectionMap ] as any
149157
let mappedValue: string
150158
if (typeof mapper === 'string') {
151159
mappedValue = mapper

src/index.ts

-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ export {
33
extractGraphQLSelectionPath,
44
extractGraphQLSelections,
55
provideDynamicResolvers,
6-
IExtractGraphQLSelectionPathParams,
76
IGraphQLExtractSelectionMap,
8-
IExtractGraphQLSelectionsParams as IParams,
97
} from './helpers'
108

119
export { NavigationProperty } from './navigation-property'

types.d.ts

+56
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,59 @@ declare type KeysMatching<T, V> = { [ K in keyof T ]-?: T[ K ] extends V ? K : n
77
* A Dictionary type for keeping `TValue` values.
88
*/
99
declare type Dictionary<TValue> = { [ key: string ]: TValue }
10+
11+
/**
12+
* Maps the given type to its function keys.
13+
* If the given type is an array, then the function indices will be returned.
14+
* If the given type is an object, then the function keys will be returned.
15+
*/
16+
declare type FunctionKeys<T>
17+
= T extends any[]
18+
? Exclude<_FunctionKeys<T>, -1>
19+
: T extends { [ key: string ]: any }
20+
? KeysMatching<T, Func>
21+
: never
22+
23+
/**
24+
* Defines the nullable version of given type.
25+
*/
26+
declare type Nullable<T> = T | null | undefined
27+
28+
/**
29+
* Defines the nullable version of given type with `void` type.
30+
*/
31+
declare type NullableReturn<T> = Nullable<T> | void
32+
33+
/**
34+
* Defines a type which can be in a promise or not.
35+
*/
36+
declare type MaybePromise<T> = Promise<T> | T
37+
38+
/**
39+
* Gets the keys of an object whose values are objects.
40+
*
41+
* This does not include function keys.
42+
*/
43+
declare type ObjectKeys<T extends object>
44+
= Exclude<KeysMatching<T, object>, FunctionKeys<T>>
45+
46+
/**
47+
* Gets the length of an array.
48+
*/
49+
declare type Length<T extends any[]> = T extends { length: infer L } ? L : never
50+
51+
/**
52+
* Builds a tuple with given length.
53+
*/
54+
declare type BuildTuple<L extends number, T extends any[] = []>
55+
= T extends { length: L } ? T : BuildTuple<L, [ ...T, any ]>
56+
57+
type _FunctionKeys<TArray extends any[], CurrentIndex = 0, Index = -1>
58+
= TArray extends [ infer H, ...infer T ]
59+
? H extends Func
60+
? _FunctionKeys<T, Add<CurrentIndex, 1>, Index | CurrentIndex>
61+
: _FunctionKeys<T, Add<CurrentIndex, 1>, Index>
62+
: Index
63+
64+
type Add<A extends number, B extends number> =
65+
Length<[ ...BuildTuple<A>, ...BuildTuple<B> ]>

0 commit comments

Comments
 (0)