Skip to content

Commit b89161e

Browse files
feat: field keywords with type infering
1 parent c5d625b commit b89161e

File tree

4 files changed

+39
-21
lines changed

4 files changed

+39
-21
lines changed

src/lib/queries/get-bool.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ describe('getBoolQuery', () => {
99
const id = faker.string.uuid()
1010
const query = getBoolQuery<HomeDocument>({
1111
should: [
12+
getTermQuery('id.keyword', id),
1213
getTermQuery('id', id),
1314
getTermsQuery('propertyType', [PropertyType.Apartment]),
14-
getBoolQuery<HomeDocument>({
15-
// ^
16-
// note: weird bug when Generic Type is not being passed
15+
getBoolQuery({
1716
must: {
1817
term: { address: { value: 'test' } }
1918
}
@@ -24,6 +23,7 @@ describe('getBoolQuery', () => {
2423
expect(query).toEqual({
2524
bool: {
2625
should: [
26+
{ term: { 'id.keyword': { value: id } } },
2727
{ term: { id: { value: id } } },
2828
{ terms: { propertyType: [PropertyType.Apartment] } },
2929
{

src/lib/queries/get-term.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1-
import { Document, Field, FieldType, Keyword } from 'lib/types'
1+
import { Document, Keyword, KeywordType } from 'lib/types'
22

3-
export type TermQueryBody<TDocument extends Document, TField extends Field<TDocument>> = {
4-
[Key in keyof TDocument]?: { value: FieldType<TDocument, TField> }
3+
export type TermQueryBody<
4+
TDocument extends Document,
5+
TKeyword extends Keyword<TDocument> = Keyword<TDocument>
6+
> = {
7+
[x in TKeyword]?: { value: KeywordType<TDocument, TKeyword> }
58
}
69

710
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8-
export type TermQuery<TDocument extends Document, TField extends Field<TDocument> = keyof TDocument> = {
9-
term: TermQueryBody<TDocument, TField>
11+
export type TermQuery<
12+
TDocument extends Document,
13+
TKeyword extends Keyword<TDocument> = Keyword<TDocument>
14+
> = {
15+
term: TermQueryBody<TDocument, TKeyword>
1016
}
1117

1218
// eslint-disable-next-line @typescript-eslint/no-explicit-any
13-
export const getTermQuery = <TDocument extends Document, TField extends keyof TDocument = keyof TDocument>
14-
(field: Keyword<TDocument, TField>, value: FieldType<TDocument, TField>): TermQuery<TDocument, TField> => ({
15-
term: { [field]: { value } } as TermQueryBody<TDocument, TField>
19+
export const getTermQuery = <
20+
TDocument extends Document,
21+
TKeyword extends Keyword<TDocument> = Keyword<TDocument>
22+
>(field: TKeyword, value: KeywordType<TDocument, TKeyword>): TermQuery<TDocument, TKeyword> => ({
23+
term: { [field]: { value } } as TermQueryBody<TDocument, TKeyword>
1624
})

src/lib/queries/get-terms.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1-
import { Document, Field, FieldType, Keyword } from 'lib/types'
1+
import { Document, Field, FieldType, Keyword, KeywordType } from 'lib/types'
22

3-
type TermsQueryBody<TDocument extends Document, TField extends Field<TDocument>> = {
4-
[Key in keyof TDocument]: Array<FieldType<TDocument, TField>>
3+
type TermsQueryBody<
4+
TDocument extends Document,
5+
TKeyword extends Keyword<TDocument> = Keyword<TDocument>
6+
> = {
7+
[x in TKeyword]?: Array<KeywordType<TDocument, TKeyword>>
58
}
69

710
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8-
export type TermsQuery<TDocument extends Document, TField extends Field<TDocument> = keyof TDocument> = {
9-
terms: TermsQueryBody<TDocument, TField>
11+
export type TermsQuery<
12+
TDocument extends Document,
13+
TKeyword extends Keyword<TDocument> = Keyword<TDocument>
14+
> = {
15+
terms: TermsQueryBody<TDocument, TKeyword>
1016
}
1117

1218
// eslint-disable-next-line @typescript-eslint/no-explicit-any
13-
export const getTermsQuery = <TDocument extends Document, TField extends Field<TDocument> = keyof TDocument>
14-
(field: Keyword<TDocument, TField>, values: Array<FieldType<TDocument, TField>>): TermsQuery<TDocument, TField> => ({
15-
terms: { [field]: values } as TermsQueryBody<TDocument, TField>
19+
export const getTermsQuery = <
20+
TDocument extends Document,
21+
TKeyword extends Keyword<TDocument> = Keyword<TDocument>
22+
>(field: TKeyword, values: Array<KeywordType<TDocument, TKeyword>>): TermsQuery<TDocument, TKeyword> => ({
23+
terms: { [field]: values } as TermsQueryBody<TDocument, TKeyword>
1624
})

src/lib/types/common.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ export type ClassConstructor<T> = new (...args: Array<any>) => T
55
export type Document = Record<string, any>
66

77
export type Field<TDocument extends Document> = keyof TDocument
8-
export type FieldType<TDocument extends Document, TKey extends Field<TDocument>> = TKey extends Field<TDocument> ? TDocument[TKey] : never
9-
export type Keyword<TDocument extends Document, TField extends Field<TDocument>> = TField | `${TField & string}.keyword`
8+
export type FieldType<TDocument extends Document, TField extends Field<TDocument>> = TDocument[TField]
9+
export type Keyword<TDocument extends Document> = (Field<TDocument> & string) | `${Field<TDocument> & string}.keyword`
10+
export type KeywordFields<TDocument extends Document> = { [K in keyof TDocument as K | `${K & string}.keyword`]: TDocument[K] }
11+
export type KeywordType<TDocument extends Document, TKeyword extends Keyword<TDocument>> = KeywordFields<TDocument>[TKeyword]

0 commit comments

Comments
 (0)