I am using react-router v5.1 with TypeScript and have this route configurations:
In this situation, your TokenPage
code is unaware it is being wrapped by a Route
. You are right that if the URL does not contain the proper parameters, your component wouldn't be rendered. But Typescript isn't aware of this.
The default typing you got there is proper and you should null check the value before using it.
If ever you would want to override the typing, useParams
is generic and accepts a type specifying the return value type.
interface ParamTypes {
tokenName: string
}
const { tokenName } = useParams<ParamTypes>()
EDIT 09/29/20
The latest typing for useParams
changed.
export function useParams<Params extends { [K in keyof Params]?: string } = {}>(): Params;
As you can see, the new default is {}
which will not imply any of the keys contained, but the generic constraints does assume that the values are of type string
.
So the following line would now yield a Property 'tokenName' does not exist on type '{}'.
TypeScript error.
const { tokenName } = useParams()
To fix this, either you type the useParams
with known parameters like in the first example, or you type it like this:
const { tokenName } = useParams<Record<string, string | undefined>>()
Since you are not specifying type for tokenName
, typescript is trying to guess which type it should be and set type to be the same as return type for useParams()
. You can try to specify type explicitly to string for tokenName
, but then probably typescript will complain for not matching types of tokenName
and useParams()
return type. You should be able to fix it with condition which check if useParams()
not returning undefined
and than to assign it to tokenName
.