TypeScript
Version requirement
Jotai requires TypeScript 5.5 or newer. Upgrade your TypeScript version if you're on 5.4 or older.
Jotai relies heavily on type inferences and requires strictNullChecks to be enabled. Consider adding "strict": true in your tsconfig.json.
#550
#802
#838
Notes
Primitive atoms are basically type inferred
const numAtom = atom(0) // primitive number atomconst strAtom = atom('') // primitive string atom
Primitive atoms can be explicitly typed
const numAtom = atom<number>(0)const numAtom = atom<number | null>(0)const arrAtom = atom<string[]>([])
Derived atoms can mostly have their types inferred
In general, this is the recommended approach since typing derived atoms can get a little confusing, particularly for those who are doing it for the first time.
# Read only derived atomsconst readOnlyAtom = atom((get) => get(numAtom))const asyncReadOnlyAtom = atom(async (get) => await get(someAsyncAtom))# Write only atomsconst writeOnlyAtom = atom(null, (_get, set, str: string) => set(fooAtom, str))const multipleArgumentsAtom = atom(null,(_get, set, valueOne: number, valueTwo: number) =>set(fooAtom, Math.max(valueOne, valueTwo)));# Read/Write atomsconst readWriteAtom = atom((get) => get(strAtom),(_get, set, num: number) => set(strAtom, String(num)))const asyncReadWriteAtom = atom(async (get) => await get(asyncStrAtom),(_get, set, num: number) => set(strAtom, String(num)))
Derived atoms can also be explicitly typed
If you encounter a situation where you need or want to explicitly type your derived atoms, you can do that as well.
const asyncStrAtom = atom<Promise<string>>(async () => 'foo')/*** For write only atoms you'll need to supply three type parameters.* The first type parameter describes the value returned from the atom. In the following example this is `null`.* The second type parameter describes the arguments (plural) you will pass to the "write" function. Even if you only* plan to have one argument, this type must be an array as show in the example.* The third type parameter describes the return value of the "write" function. Normally, there is no return value,* which is why we use `void` in the example below.*/const writeOnlyAtom = atom<null, [string, number], void>(null,(_get, set, stringValue, numberValue) => set(fooAtom, stringValue),)/*** Read/Write atoms also take the same three type parameters.* Just for the sake of completeness, in this example, we show that the first type parameter* can also describe an async atom.*/const readWriteAtom = atom<Promise<string>, [number], void>(async (get) => await get(asyncStrAtom),(_get, set, num) => set(strAtom, String(num)),)
useAtom is typed based on atom types
const [num, setNum] = useAtom(primitiveNumAtom)const [num] = useAtom(readOnlyNumAtom)const [, setNum] = useAtom(writeOnlyNumAtom)
Access to the value type of an atom
import { ExtractAtomValue, useAtomValue } from 'jotai'import { userAtom } from 'state'import { useQuery } from '@tanstack/react-query'export default function WriteReview(hid) {const user = useAtomValue(userAtom)const res = useGetReviewQuery(user)}function useGetReviewQuery(user: ExtractAtomValue<typeof userAtom>) {return fetch('/api/user/' + user.id + '/review')}