1

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 };
5
  • 3
    Which part don't you understand? Commented Sep 13, 2022 at 8:17
  • I think im beginning to grasp it. I see now my question could have been worded better. Commented Sep 13, 2022 at 8:35
  • But for the sake of completing the question, 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? Commented Sep 13, 2022 at 8:38
  • 1
    Type assertion does not remove properties from an object. Types only exist in typescript. When it eventually compiled to javascript, regardless of what type an object is, it is still just an object. The object retains all of its properties unless you explicitly delete them. Commented Sep 13, 2022 at 8:41
  • 1
    If user.customClaims has no role but typed as any to bypass type check, you will later get an undefined when you try to access customClaims.role. If user.customClaims is explicitly typed, you will get a compiler error saying "Property 'role' is missing in type '...' " Commented Sep 13, 2022 at 8:46

1 Answer 1

1

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).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.