Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@
"label": "Devtools",
"to": "framework/angular/devtools"
},
{
"label": "TypeScript",
"to": "framework/angular/typescript"
},
{
"label": "Zoneless",
"to": "framework/angular/zoneless"
Expand Down
1 change: 1 addition & 0 deletions docs/framework/angular/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { lastValueFrom } from 'rxjs'
import {
injectMutation,
injectQuery,
QueryClient
} from '@tanstack/angular-query-experimental'

@Component({
Expand Down
174 changes: 174 additions & 0 deletions docs/framework/angular/typescript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
id: typescript
title: TypeScript
ref: docs/framework/react/typescript.md
replace:
{
'useQuery': 'injectQuery',
'useMutation': 'injectMutation',
'react-query': 'angular-query-experimental',
'public API of React Query': 'public API of TanStack Query and - after the experimental phase, the angular-query package',
'still follows': 'still follow',
'React Query': 'TanStack Query',
'`success`': '`isSuccess()`',
'function:': 'function.',
'separate function': 'separate function or a service',
}
---

[//]: # 'TypeInference1'

```angular-ts
@Component({
// ...
template: `@let data = query.data();`,
// ^? data: number | undefined
})
class MyComponent {
query = injectQuery(() => ({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
}))
}
```

[//]: # 'TypeInference1'
[//]: # 'TypeInference2'

```angular-ts
@Component({
// ...
template: `@let data = query.data();`,
// ^? data: string | undefined
})
class MyComponent {
query = injectQuery(() => ({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
}))
}
```

[//]: # 'TypeInference2'
[//]: # 'TypeInference3'

In this example we pass Group[] to the type parameter of HttpClient's `get` method.

```angular-ts
@Component({
template: `@let data = query.data();`,
// ^? data: Group[] | undefined
})
class MyComponent {
http = inject(HttpClient)

query = injectQuery(() => ({
queryKey: ['groups'],
queryFn: () => lastValueFrom(this.http.get<Group[]>('/groups')),
}))
}
```

[//]: # 'TypeInference3'
[//]: # 'TypeInference4'

```angular-ts
@Component({
// ...
template: `
@if (query.isSuccess()) {
@let data = query.data();
// ^? data: number
}
`,
})
class MyComponent {
query = injectQuery(() => ({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
}))
}
```

> TypeScript currently does not support discriminated unions on object methods. Narrowing on signal fields on objects such as query results only works on signals returning a boolean. Prefer using `isSuccess()` and similar boolean status signals over `status() === 'success'`.

[//]: # 'TypeInference4'
[//]: # 'TypingError'

```angular-ts
@Component({
// ...
template: `@let error = query.error();`,
// ^? error: Error | null
})
class MyComponent {
query = injectQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups
}))
}
```

[//]: # 'TypingError'
[//]: # 'TypingError2'

```angular-ts
@Component({
// ...
template: `@let error = query.error();`,
// ^? error: string | null
})
class MyComponent {
query = injectQuery<Group[], string>(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))
}
```

[//]: # 'TypingError2'
[//]: # 'TypingError3'

```ts
import axios from 'axios'

query = injectQuery(() => ({ queryKey: ['groups'], queryFn: fetchGroups }))

computed(() => {
const error = query.error()
// ^? error: Error | null

if (axios.isAxiosError(error)) {
error
// ^? const error: AxiosError
}
})
```

[//]: # 'TypingError3'
[//]: # 'RegisterErrorType'

```ts
import '@tanstack/angular-query-experimental'

declare module '@tanstack/angular-query-experimental' {
interface Register {
defaultError: AxiosError
}
}

const query = injectQuery(() => ({
queryKey: ['groups'],
queryFn: fetchGroups,
}))

computed(() => {
const error = query.error()
// ^? error: AxiosError | null
})
```

[//]: # 'RegisterErrorType'
[//]: # 'Materials'
[//]: # 'Materials'
2 changes: 1 addition & 1 deletion docs/framework/react/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ declare module '@tanstack/react-query' {

## Typing Query Options

If you inline query options into `useQuery`, you'll get automatic type inference. However, you might want to extract the query options into a separate function to share them between `useQuery` and e.g. `prefetchQuery`. In that case, you'd lose type inference. To get it back, you can use `queryOptions` helper:
If you inline query options into `useQuery`, you'll get automatic type inference. However, you might want to extract the query options into a separate function to share them between `useQuery` and e.g. `prefetchQuery`. In that case, you'd lose type inference. To get it back, you can use the `queryOptions` helper:

```ts
import { queryOptions } from '@tanstack/react-query'
Expand Down