Reputation: 103
I have an error message:
Type 'null' is not assignable to type 'string'.
I found a solution here but I didn't understand the answers for my problem.
My code is presented like this:
const expectedRole = route.data['expectedRole'];
const token = localStorage.getItem('token');
const { userName, roleId } = decode(token);
console.log(roleId);
Edit 2022-02-02
decode method
export class InvalidTokenError extends Error {}
export interface JwtDecodeOptions {
header?: boolean;
}
export interface JwtHeader {
type?: string;
alg?: string;
}
export interface JwtPayload {
iss?: string;
sub?: string;
aud?: string[] | string;
exp?: number;
nbf?: number;
iat?: number;
jti?: string;
}
export default function jwtDecode<T = unknown>(
token: string,
options?: JwtDecodeOptions
): T;
FYI, I copied the code from the project here
Upvotes: 1
Views: 22495
Reputation: 21
I was able to fix the problem by modifying this:
export class RoleGuard implements CanActivate {
constructor(
private authService: AuthService,
public router: Router
){ }
canActivate(route: ActivatedRouteSnapshot):boolean{
const expectedRole = route.data.expectedRole;
const token = localStorage.getItem('token');
const { userName, roleId } = decode(token);
console.log(roleId);
if( !this.authService.isAuth() || roleId !== expectedRole){
console.log('Usuario no autorizado para la vista');
this.router.navigate(['login']);
return false;
}
return true;
}
}
To this:
export class RoleGuard implements CanActivate {
constructor(
private authService: AuthService,
public router: Router
) { }
canActivate(route: ActivatedRouteSnapshot): boolean {
const expectedRole = route.data['expectedRole'];
const token = localStorage.getItem('token');
if (!this.authService.isAuth()) {
console.log('Usuario no autorizado para la vista');
this.router.navigate(['login']);
};
const info: { userName: string, roleId: string } = decode(token);
if (info.roleId != expectedRole) {
console.log('Usuario no autorizado para la vista');
this.router.navigate(['login']);
return false;
}
return true;
}
}
I separated the if
into two if
s, each one performing an independent activity.
Upvotes: 2
Reputation: 10946
This is just the typescript compiler telling you that token
may be null
. So you need to check that it isn't before using it in the decode
function, since decode
does not accept a null
parameter.
const expectedRole = route.data['expectedRole'];
const token = localStorage.getItem('token');
if (token) const { userName, roleId } = decode(token);
console.log(roleId);
You can also force the typescript compiler to ignore this using !
, which says "this variable will be truthy, trust me", but you need to be absolutely sure it will never be null
, or you may get a runtime error.
const expectedRole = route.data['expectedRole'];
const token = localStorage.getItem('token');
const { userName, roleId } = decode(token!);
console.log(roleId);
Edit
This solution should work regardless, but you should define the correct return types for decode
const expectedRole = route.data['expectedRole'];
const token = localStorage.getItem('token');
if (token) const info: { userName, roleId } = decode(token);
console.log(info.roleId);
OR
const expectedRole = route.data['expectedRole'];
const token = localStorage.getItem('token');
if (token) const info: any = decode(token);
console.log(info.roleId);
Edit 2
Looks like decode
is a generic function, so you can define the return type like this:
const expectedRole = route.data['expectedRole'];
const token = localStorage.getItem('token');
if (token) const { userName, roleId } = decode<{ userName, roleId }>(token);
console.log(roleId);
Upvotes: 3
Reputation: 389
Thinking like typescript thinks, you need to define a type (i.e. "string", "number", "void") for variables as well as functions or methods.
Ones you have defined type for variables (or for methods), typescript check if its type match with its definition.
In your case token
is probably null and typescript alert you that string not match with null and rise an error.
So you need to debug token and check if:
In some cases you need to declare type of variable in the following way:
token: string = ...
Upvotes: 0