Generated Types
To add to the TypeScript (and JavaScript!) experience, Redwood generates types for you. These generated types not only include your GraphQL operations, but also your named routes, Cells, scenarios, and tests.
When you run yarn rw dev, the CLI watches files for changes and triggers type generation automatically, but you can trigger it manually too:
yarn rw g types
# or
# yarn redwood generate types
If you're getting errors trying to generate types, it's worth checking the GraphQL operations in your Cells and SDLs.
Make sure that they're syntactically valid, and that every query and mutation on the web side is defined in an *.sdl.js file on the api side.
If you're curious, you can find the generated types in the .redwood/types, web/types/graphql.d.ts, and api/types/graphql.d.ts directories. Broadly speaking, Redwood generates the following types:
- "mirror" types for your components, pages, layouts, etc. on the web side, and for your services, lib, etc. on the api side
- types based on your queries and mutations on the web side (in
web/types/graphql.d.ts) - types for resolvers based on your SDLs on the api side (in
api/types/graphql.d.ts) - types for testing,
currentUser, etc. - types for certain functions like
routes.pageName()anduseAuth()
CurrentUser
If you've setup auth, the type for the current user on both the web and the api side gets automatically "inferred" from the getCurrentUser function in api/src/lib/auth.ts.
For example, if you specify the return type on getCurrentUser as...
interface MyCurrentUser {
id: string
roles: string[]
email: string
projectId: number
}
const getCurrentUser = ({ decoded }): MyCurrentUser => {
//..
}
The types for both useAuth().currentUser on the web side and context.currentUser on the api side will be the same—the MyCurrentUser interface.
context.currentUser unknown?This usually happens when you don't have the various generated and utility types in your project.
Run yarn rw g types, and just to be sure, restart your TS server.
In VSCode, you can do this by running "TypeScript: Restart TS server" in the command palette (Cmd+Shift+P on Mac, Ctrl+Shift+P on Windows)
Query and Mutation types
Let's say you have a query in a Cell that looks like this:
export const QUERY = gql`
# 👇 Make sure to name your GraphQL operations
query FindBlogPostQuery($id: Int!) {
blogPost: post(id: $id) {
title
body
}
}
`
Redwood generates types for both the data returned from the query and the query's variables.
These generated types will use the query's name—in this case, FindBlogPostQuery—so you can import them like this:
import type {
FindBlogPostQuery,
FindBlogPostQueryVariables,
} from 'types/graphql'
FindBlogPostQuery is the type of the data returned from the query ({ title: string, body: string }) and FindBlogPostQueryVariables is the type of the query's variables ({ id: number }).
The import statement's specifier, 'types/graphql', is a mapped path. First, TypeScript will look for the types in web/types/graphql.d.ts; if they're not there, it'll check types/graphql.d.ts. Redwood only automatically generates the former. For the latter, see sharing types between sides.
But don't worry too much. If you use the generators, they template all of this for you!