Reputation: 123
Im looking for an explanation of the use of such syntax. I wont bore with my interpretation.
Updated with improved questions :
Would const customClaims only have 1 attribute?
Does that as { role? : string }
remove other attributes as well?
What if user custom claims has no role attribute?
const customClaims = (user.customClaims || {role: ""}) as { role?: string };
Upvotes: 1
Views: 99
Reputation: 944568
Let's break this down.
(user.customClaims || {role: ""})
is an expression that result in a value (let's call it 𝒳).
If user.customClaims
is a true value, then 𝒳 is user.customClaims
. Otherwise 𝒳 is {role: ""}
as { role?: string }
tells TypeScript that 𝒳 is a value which conforms to the type { role?: string }
.
It does not alter the value of 𝒳 at all.
If 𝒳 has extra properties then it keeps them, but TypeScript doesn't know about them.
Consider:
const foo = { role: "a", value: { x: "y" } };
const bar = (foo || {role: ""}) as { role?: string };
console.log(bar);
bar
has a value
property so the output of this will be:
{ role: 'a', value: { x: 'y' } }
but if you change the last line to console.log(bar.value);
TypeScript will error with:
Property 'value' does not exist on type '{ role?: string | undefined; }'.
If 𝒳 hasn't got a role
property then it still doesn't. Since the type definition makes the role
optional, then that isn't a problem.
If 𝒳 has a role
property but it isn't a string, TypeScript will believe the value is a string so you could get a runtime error.
Consider:
const foo = { role: { x: "y" } } as unknown;
const bar = (foo || {role: ""}) as { role?: string };
console.log(bar.role?.charAt(0));
This will error at runtime because objects, unlike strings, don't have a charAt
method.
(NB: In this simple example, TypeScript knows enough about the object assigned to foo
that it can work out as { role?: string }
is a mistake if I don't use as unknown
first).
Upvotes: 1