Skip to content

Commit db40d7b

Browse files
authored
fix(sdk): correct return types with select (#15289)
Fixes #15279
1 parent 9a1eb77 commit db40d7b

8 files changed

Lines changed: 57 additions & 24 deletions

File tree

packages/sdk/src/collections/delete.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type {
1111
export type DeleteBaseOptions<
1212
T extends PayloadTypesShape,
1313
TSlug extends CollectionSlug<T>,
14-
TSelect extends SelectType,
14+
TSelect extends SelectFromCollectionSlug<T, TSlug>,
1515
> = {
1616
/**
1717
* the Collection slug to operate against.

packages/sdk/src/collections/find.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ import type {
99
} from 'payload'
1010

1111
import type { PayloadSDK } from '../index.js'
12-
import type { JoinQuery, PopulateType, TransformCollectionWithSelect } from '../types.js'
12+
import type {
13+
JoinQuery,
14+
PopulateType,
15+
SelectFromCollectionSlug,
16+
TransformCollectionWithSelect,
17+
} from '../types.js'
1318

1419
export type FindOptions<
1520
T extends PayloadTypesShape,
1621
TSlug extends CollectionSlug<T>,
17-
TSelect extends SelectType,
22+
TSelect extends SelectFromCollectionSlug<T, TSlug>,
1823
> = {
1924
/**
2025
* the Collection slug to operate against.
@@ -89,7 +94,7 @@ export type FindOptions<
8994
export async function find<
9095
T extends PayloadTypesShape,
9196
TSlug extends CollectionSlug<T>,
92-
TSelect extends SelectType,
97+
TSelect extends SelectFromCollectionSlug<T, TSlug>,
9398
>(
9499
sdk: PayloadSDK<T>,
95100
options: FindOptions<T, TSlug, TSelect>,

packages/sdk/src/collections/findByID.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
import type {
2-
ApplyDisableErrors,
3-
CollectionSlug,
4-
PayloadTypesShape,
5-
SelectType,
6-
TypedLocale,
7-
} from 'payload'
1+
import type { ApplyDisableErrors, CollectionSlug, PayloadTypesShape, TypedLocale } from 'payload'
82

93
import type { PayloadSDK } from '../index.js'
10-
import type { JoinQuery, PopulateType, TransformCollectionWithSelect } from '../types.js'
4+
import type {
5+
JoinQuery,
6+
PopulateType,
7+
SelectFromCollectionSlug,
8+
TransformCollectionWithSelect,
9+
} from '../types.js'
1110

1211
export type FindByIDOptions<
1312
T extends PayloadTypesShape,
1413
TSlug extends CollectionSlug<T>,
1514
TDisableErrors extends boolean,
16-
TSelect extends SelectType,
15+
TSelect extends SelectFromCollectionSlug<T, TSlug>,
1716
> = {
1817
/**
1918
* the Collection slug to operate against.
@@ -63,7 +62,7 @@ export async function findByID<
6362
T extends PayloadTypesShape,
6463
TSlug extends CollectionSlug<T>,
6564
TDisableErrors extends boolean,
66-
TSelect extends SelectType,
65+
TSelect extends SelectFromCollectionSlug<T, TSlug>,
6766
>(
6867
sdk: PayloadSDK<T>,
6968
options: FindByIDOptions<T, TSlug, TDisableErrors, TSelect>,

packages/sdk/src/collections/update.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { resolveFileFromOptions } from '../utilities/resolveFileFromOptions.js'
2222
export type UpdateBaseOptions<
2323
T extends PayloadTypesShape,
2424
TSlug extends CollectionSlug<T>,
25-
TSelect extends SelectType,
25+
TSelect extends SelectFromCollectionSlug<T, TSlug>,
2626
> = {
2727
/**
2828
* Whether the current update should be marked as from autosave.

packages/sdk/src/globals/update.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { GlobalSlug, PayloadTypesShape, SelectType, TypedLocale } from 'payload'
1+
import type { GlobalSlug, PayloadTypesShape, TypedLocale } from 'payload'
22
import type { DeepPartial } from 'ts-essentials'
33

44
import type { PayloadSDK } from '../index.js'
@@ -12,7 +12,7 @@ import type {
1212
export type UpdateGlobalOptions<
1313
T extends PayloadTypesShape,
1414
TSlug extends GlobalSlug<T>,
15-
TSelect extends SelectType,
15+
TSelect extends SelectFromGlobalSlug<T, TSlug>,
1616
> = {
1717
/**
1818
* The global data to update.

packages/sdk/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ export class PayloadSDK<T extends PayloadTypesShape = PayloadTypes> {
196196
* @param options
197197
* @returns documents satisfying query
198198
*/
199-
find<TSlug extends CollectionSlug<T>, TSelect extends SelectType>(
199+
find<TSlug extends CollectionSlug<T>, TSelect extends SelectFromCollectionSlug<T, TSlug>>(
200200
options: FindOptions<T, TSlug, TSelect>,
201201
init?: RequestInit,
202202
): Promise<PaginatedDocs<TransformCollectionWithSelect<T, TSlug, TSelect>>> {
@@ -211,7 +211,7 @@ export class PayloadSDK<T extends PayloadTypesShape = PayloadTypes> {
211211
findByID<
212212
TSlug extends CollectionSlug<T>,
213213
TDisableErrors extends boolean,
214-
TSelect extends SelectType,
214+
TSelect extends SelectFromCollectionSlug<T, TSlug>,
215215
>(
216216
options: FindByIDOptions<T, TSlug, TDisableErrors, TSelect>,
217217
init?: RequestInit,

packages/sdk/src/types.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
SelectType,
88
Sort,
99
TransformDataWithSelect,
10+
TypedCollectionSelect,
1011
TypeWithID,
1112
Where,
1213
} from 'payload'
@@ -33,27 +34,35 @@ export type DataFromGlobalSlug<
3334
export type SelectFromCollectionSlug<
3435
T extends PayloadTypesShape,
3536
TSlug extends CollectionSlug<T>,
36-
> = SelectType & T['collectionsSelect'][TSlug]
37+
> = TSlug extends keyof T['collectionsSelect'] ? T['collectionsSelect'][TSlug] : SelectType
3738

3839
export type SelectFromGlobalSlug<
3940
T extends PayloadTypesShape,
4041
TSlug extends GlobalSlug<T>,
41-
> = SelectType & T['globalsSelect'][TSlug]
42+
> = TSlug extends keyof T['globalsSelect'] ? T['globalsSelect'][TSlug] : SelectType
4243

4344
export type TransformCollectionWithSelect<
4445
T extends PayloadTypesShape,
4546
TSlug extends CollectionSlug<T>,
4647
TSelect,
4748
> = TSelect extends SelectType
48-
? TransformDataWithSelect<(JsonObject & TypeWithID) & T['collections'][TSlug], TSelect>
49+
? TransformDataWithSelect<
50+
T['collections'][TSlug] extends JsonObject
51+
? T['collections'][TSlug]
52+
: JsonObject & TypeWithID,
53+
TSelect
54+
>
4955
: T['collections'][TSlug]
5056

5157
export type TransformGlobalWithSelect<
5258
T extends PayloadTypesShape,
5359
TSlug extends GlobalSlug<T>,
5460
TSelect,
5561
> = TSelect extends SelectType
56-
? TransformDataWithSelect<JsonObject & T['globals'][TSlug], TSelect>
62+
? TransformDataWithSelect<
63+
T['globals'][TSlug] extends JsonObject ? T['globals'][TSlug] : JsonObject & TypeWithID,
64+
TSelect
65+
>
5766
: T['globals'][TSlug]
5867

5968
type SystemFields = 'createdAt' | 'id' | 'sizes' | 'updatedAt'

test/types/types.spec.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ describe('Types testing', () => {
963963
radioField: 'option-1',
964964
},
965965
})
966-
expect(result).type.toBe<JsonObject & LocalConfig['collections']['posts'] & TypeWithID>()
966+
expect(result).type.toBe<LocalConfig['collections']['posts']>()
967967
})
968968

969969
test('SDK create data should be typed and reject invalid properties', () => {
@@ -983,6 +983,26 @@ describe('Types testing', () => {
983983
}),
984984
).type.toRaiseError()
985985
})
986+
987+
test('SDK with select in findByID returns correct types', async () => {
988+
const _sdk = new PayloadSDK<LocalConfig>({ baseURL: '' })
989+
const result = await _sdk.findByID({
990+
collection: 'posts',
991+
id: 'id',
992+
select: { title: true, namedGroup: true },
993+
})
994+
expect(result).type.toBe<Pick<Post, 'id' | 'namedGroup' | 'title'>>()
995+
})
996+
997+
test('SDK with select excluding field in findByID returns correct types', async () => {
998+
const _sdk = new PayloadSDK<LocalConfig>({ baseURL: '' })
999+
const result = await _sdk.findByID({
1000+
collection: 'posts',
1001+
id: 'id',
1002+
select: { richText: false },
1003+
})
1004+
expect(result).type.toBe<Omit<Post, 'richText'>>()
1005+
})
9861006
})
9871007

9881008
describe('strictDraftTypes flag', () => {

0 commit comments

Comments
 (0)