Skip to content

Commit 2399bb0

Browse files
authoredJan 27, 2025··
feat(types): type narrowing for isPlaceholderData (#8586)
* feat(types): type narrowing for isPlaceholderData * fix: infiniteQueryObserver types * fix: typing issues 🤷‍♂️ * chore: add missing tsconfig.legacy.json files * fix: run type-tests in serial
1 parent 97f5544 commit 2399bb0

File tree

24 files changed

+319
-50
lines changed

24 files changed

+319
-50
lines changed
 

‎packages/angular-query-devtools-experimental/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./build ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
2323
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
2424
"test:types:ts53": "node ../../node_modules/typescript53/lib/tsc.js --build",
@@ -57,6 +57,7 @@
5757
"@angular/platform-browser-dynamic": "^19.1.0-next.0",
5858
"@tanstack/angular-query-experimental": "workspace:*",
5959
"eslint-plugin-jsdoc": "^50.5.0",
60+
"npm-run-all": "^4.1.5",
6061
"tsup": "8.0.2",
6162
"typescript": "5.7.2"
6263
},

‎packages/angular-query-experimental/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"clean": "premove ./build ./coverage ./dist-ts",
3131
"compile": "tsc --build",
3232
"test:eslint": "eslint ./src",
33-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
33+
"test:types": "npm-run-all --serial test:types:*",
3434
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build",
3535
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
3636
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
@@ -75,6 +75,7 @@
7575
"@angular/platform-browser-dynamic": "^19.1.0-next.0",
7676
"@microsoft/api-extractor": "^7.48.1",
7777
"eslint-plugin-jsdoc": "^50.5.0",
78+
"npm-run-all": "^4.1.5",
7879
"tsup": "8.0.2",
7980
"typescript": "5.7.2"
8081
},

‎packages/eslint-plugin-query/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./dist ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build",
2323
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
2424
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
@@ -61,7 +61,8 @@
6161
"devDependencies": {
6262
"@typescript-eslint/rule-tester": "^8.18.1",
6363
"combinate": "^1.1.11",
64-
"eslint": "^9.15.0"
64+
"eslint": "^9.15.0",
65+
"npm-run-all": "^4.1.5"
6566
},
6667
"peerDependencies": {
6768
"eslint": "^8.57.0 || ^9.0.0"

‎packages/query-async-storage-persister/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./build ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build",
2323
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
2424
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
@@ -57,5 +57,8 @@
5757
],
5858
"dependencies": {
5959
"@tanstack/query-persist-client-core": "workspace:*"
60+
},
61+
"devDependencies": {
62+
"npm-run-all": "^4.1.5"
6063
}
6164
}

‎packages/query-broadcast-client-experimental/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./build ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build",
2323
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
2424
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
@@ -56,5 +56,8 @@
5656
"dependencies": {
5757
"@tanstack/query-core": "workspace:*",
5858
"broadcast-channel": "^7.0.0"
59+
},
60+
"devDependencies": {
61+
"npm-run-all": "^4.1.5"
5962
}
6063
}

‎packages/query-core/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./build ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build tsconfig.legacy.json",
2323
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build tsconfig.legacy.json",
2424
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build tsconfig.legacy.json",
@@ -56,6 +56,7 @@
5656
"!src/__tests__"
5757
],
5858
"devDependencies": {
59-
"@testing-library/dom": "^10.4.0"
59+
"@testing-library/dom": "^10.4.0",
60+
"npm-run-all": "^4.1.5"
6061
}
6162
}

‎packages/query-core/src/__tests__/infiniteQueryObserver.test-d.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,22 @@ describe('InfiniteQueryObserver', () => {
3232
expectTypeOf(result.error).toEqualTypeOf<null>()
3333
expectTypeOf(result.isLoading).toEqualTypeOf<boolean>()
3434
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
35+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
3536
}
3637

3738
if (result.isLoading) {
3839
expectTypeOf(result.data).toEqualTypeOf<undefined>()
3940
expectTypeOf(result.error).toEqualTypeOf<null>()
4041
expectTypeOf(result.isPending).toEqualTypeOf<true>()
4142
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
43+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
4244
}
4345

4446
if (result.isLoadingError) {
4547
expectTypeOf(result.data).toEqualTypeOf<undefined>()
4648
expectTypeOf(result.error).toEqualTypeOf<Error>()
4749
expectTypeOf(result.status).toEqualTypeOf<'error'>()
50+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
4851
}
4952

5053
if (result.isRefetchError) {
@@ -53,12 +56,20 @@ describe('InfiniteQueryObserver', () => {
5356
expectTypeOf(result.status).toEqualTypeOf<'error'>()
5457
expectTypeOf(result.isFetchNextPageError).toEqualTypeOf<boolean>()
5558
expectTypeOf(result.isFetchPreviousPageError).toEqualTypeOf<boolean>()
59+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
5660
}
5761

5862
if (result.isSuccess) {
5963
expectTypeOf(result.data).toEqualTypeOf<InfiniteData<string, unknown>>()
6064
expectTypeOf(result.error).toEqualTypeOf<null>()
6165
expectTypeOf(result.status).toEqualTypeOf<'success'>()
66+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<boolean>()
67+
}
68+
69+
if (result.isPlaceholderData) {
70+
expectTypeOf(result.data).toEqualTypeOf<InfiniteData<string, unknown>>()
71+
expectTypeOf(result.error).toEqualTypeOf<null>()
72+
expectTypeOf(result.status).toEqualTypeOf<'success'>()
6273
}
6374
})
6475
})

‎packages/query-core/src/__tests__/queryObserver.test-d.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ describe('queryObserver', () => {
3232
expectTypeOf(result.isLoadingError).toEqualTypeOf<false>()
3333
expectTypeOf(result.isRefetchError).toEqualTypeOf<false>()
3434
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
35+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
3536
}
3637
if (result.isLoading) {
3738
expectTypeOf(result.data).toEqualTypeOf<undefined>()
@@ -43,6 +44,7 @@ describe('queryObserver', () => {
4344
expectTypeOf(result.isRefetchError).toEqualTypeOf<false>()
4445
expectTypeOf(result.isSuccess).toEqualTypeOf<false>()
4546
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
47+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
4648
}
4749

4850
if (result.isLoadingError) {
@@ -55,6 +57,7 @@ describe('queryObserver', () => {
5557
expectTypeOf(result.isRefetchError).toEqualTypeOf<false>()
5658
expectTypeOf(result.isSuccess).toEqualTypeOf<false>()
5759
expectTypeOf(result.status).toEqualTypeOf<'error'>()
60+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
5861
}
5962

6063
if (result.isRefetchError) {
@@ -67,6 +70,7 @@ describe('queryObserver', () => {
6770
expectTypeOf(result.isRefetchError).toEqualTypeOf<true>()
6871
expectTypeOf(result.isSuccess).toEqualTypeOf<false>()
6972
expectTypeOf(result.status).toEqualTypeOf<'error'>()
73+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<false>()
7074
}
7175

7276
if (result.isSuccess) {
@@ -79,6 +83,20 @@ describe('queryObserver', () => {
7983
expectTypeOf(result.isRefetchError).toEqualTypeOf<false>()
8084
expectTypeOf(result.isSuccess).toEqualTypeOf<true>()
8185
expectTypeOf(result.status).toEqualTypeOf<'success'>()
86+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<boolean>()
87+
}
88+
89+
if (result.isPlaceholderData) {
90+
expectTypeOf(result.data).toEqualTypeOf<{ value: string }>()
91+
expectTypeOf(result.error).toEqualTypeOf<null>()
92+
expectTypeOf(result.isError).toEqualTypeOf<false>()
93+
expectTypeOf(result.isPending).toEqualTypeOf<false>()
94+
expectTypeOf(result.isLoading).toEqualTypeOf<false>()
95+
expectTypeOf(result.isLoadingError).toEqualTypeOf<false>()
96+
expectTypeOf(result.isRefetchError).toEqualTypeOf<false>()
97+
expectTypeOf(result.isSuccess).toEqualTypeOf<true>()
98+
expectTypeOf(result.status).toEqualTypeOf<'success'>()
99+
expectTypeOf(result.isPlaceholderData).toEqualTypeOf<true>()
82100
}
83101
})
84102

‎packages/query-core/src/types.ts

+46
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ export interface QueryObserverPendingResult<
791791
isLoadingError: false
792792
isRefetchError: false
793793
isSuccess: false
794+
isPlaceholderData: false
794795
status: 'pending'
795796
}
796797

@@ -806,6 +807,7 @@ export interface QueryObserverLoadingResult<
806807
isLoadingError: false
807808
isRefetchError: false
808809
isSuccess: false
810+
isPlaceholderData: false
809811
status: 'pending'
810812
}
811813

@@ -821,6 +823,7 @@ export interface QueryObserverLoadingErrorResult<
821823
isLoadingError: true
822824
isRefetchError: false
823825
isSuccess: false
826+
isPlaceholderData: false
824827
status: 'error'
825828
}
826829

@@ -836,6 +839,7 @@ export interface QueryObserverRefetchErrorResult<
836839
isLoadingError: false
837840
isRefetchError: true
838841
isSuccess: false
842+
isPlaceholderData: false
839843
status: 'error'
840844
}
841845

@@ -851,6 +855,23 @@ export interface QueryObserverSuccessResult<
851855
isLoadingError: false
852856
isRefetchError: false
853857
isSuccess: true
858+
isPlaceholderData: false
859+
status: 'success'
860+
}
861+
862+
export interface QueryObserverPlaceholderResult<
863+
TData = unknown,
864+
TError = DefaultError,
865+
> extends QueryObserverBaseResult<TData, TError> {
866+
data: TData
867+
isError: false
868+
error: null
869+
isPending: false
870+
isLoading: false
871+
isLoadingError: false
872+
isRefetchError: false
873+
isSuccess: true
874+
isPlaceholderData: true
854875
status: 'success'
855876
}
856877

@@ -866,6 +887,7 @@ export type QueryObserverResult<TData = unknown, TError = DefaultError> =
866887
| QueryObserverLoadingErrorResult<TData, TError>
867888
| QueryObserverLoadingResult<TData, TError>
868889
| QueryObserverPendingResult<TData, TError>
890+
| QueryObserverPlaceholderResult<TData, TError>
869891

870892
export interface InfiniteQueryObserverBaseResult<
871893
TData = unknown,
@@ -922,6 +944,7 @@ export interface InfiniteQueryObserverPendingResult<
922944
isFetchNextPageError: false
923945
isFetchPreviousPageError: false
924946
isSuccess: false
947+
isPlaceholderData: false
925948
status: 'pending'
926949
}
927950

@@ -939,6 +962,7 @@ export interface InfiniteQueryObserverLoadingResult<
939962
isFetchNextPageError: false
940963
isFetchPreviousPageError: false
941964
isSuccess: false
965+
isPlaceholderData: false
942966
status: 'pending'
943967
}
944968

@@ -956,6 +980,7 @@ export interface InfiniteQueryObserverLoadingErrorResult<
956980
isFetchNextPageError: false
957981
isFetchPreviousPageError: false
958982
isSuccess: false
983+
isPlaceholderData: false
959984
status: 'error'
960985
}
961986

@@ -971,6 +996,7 @@ export interface InfiniteQueryObserverRefetchErrorResult<
971996
isLoadingError: false
972997
isRefetchError: true
973998
isSuccess: false
999+
isPlaceholderData: false
9741000
status: 'error'
9751001
}
9761002

@@ -988,6 +1014,25 @@ export interface InfiniteQueryObserverSuccessResult<
9881014
isFetchNextPageError: false
9891015
isFetchPreviousPageError: false
9901016
isSuccess: true
1017+
isPlaceholderData: false
1018+
status: 'success'
1019+
}
1020+
1021+
export interface InfiniteQueryObserverPlaceholderResult<
1022+
TData = unknown,
1023+
TError = DefaultError,
1024+
> extends InfiniteQueryObserverBaseResult<TData, TError> {
1025+
data: TData
1026+
isError: false
1027+
error: null
1028+
isPending: false
1029+
isLoading: false
1030+
isLoadingError: false
1031+
isRefetchError: false
1032+
isSuccess: true
1033+
isPlaceholderData: true
1034+
isFetchNextPageError: false
1035+
isFetchPreviousPageError: false
9911036
status: 'success'
9921037
}
9931038

@@ -1006,6 +1051,7 @@ export type InfiniteQueryObserverResult<
10061051
| InfiniteQueryObserverLoadingErrorResult<TData, TError>
10071052
| InfiniteQueryObserverLoadingResult<TData, TError>
10081053
| InfiniteQueryObserverPendingResult<TData, TError>
1054+
| InfiniteQueryObserverPlaceholderResult<TData, TError>
10091055

10101056
export type MutationKey = Register extends {
10111057
mutationKey: infer TMutationKey

‎packages/query-devtools/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./build ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build",
2323
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
2424
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
@@ -70,6 +70,7 @@
7070
"@tanstack/query-core": "workspace:*",
7171
"clsx": "^2.1.1",
7272
"goober": "^2.1.16",
73+
"npm-run-all": "^4.1.5",
7374
"solid-js": "^1.9.3",
7475
"solid-transition-group": "^0.2.3",
7576
"superjson": "^2.2.1",

‎packages/query-persist-client-core/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./build ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build",
2323
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
2424
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
@@ -57,5 +57,8 @@
5757
],
5858
"dependencies": {
5959
"@tanstack/query-core": "workspace:*"
60+
},
61+
"devDependencies": {
62+
"npm-run-all": "^4.1.5"
6063
}
6164
}

‎packages/query-sync-storage-persister/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"clean": "premove ./build ./coverage ./dist-ts",
1919
"compile": "tsc --build",
2020
"test:eslint": "eslint ./src",
21-
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
21+
"test:types": "npm-run-all --serial test:types:*",
2222
"test:types:ts50": "node ../../node_modules/typescript50/lib/tsc.js --build",
2323
"test:types:ts51": "node ../../node_modules/typescript51/lib/tsc.js --build",
2424
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js --build",
@@ -58,5 +58,8 @@
5858
"dependencies": {
5959
"@tanstack/query-core": "workspace:*",
6060
"@tanstack/query-persist-client-core": "workspace:*"
61+
},
62+
"devDependencies": {
63+
"npm-run-all": "^4.1.5"
6164
}
6265
}

0 commit comments

Comments
 (0)
Please sign in to comment.