Home > other >  Is it correct to combine ? and ! in Typescript?
Is it correct to combine ? and ! in Typescript?

Time:02-23

I have a user hook from Auth0:

const { user } = useUser();

It returns a user object with the following types:

user: UserProfile | undefined

I am accessing the user.sub and user.email properties with the following types:

UserProfile.sub?: string | null | undefined
userProfile.email?: string | null | undefined

I've tried to use this object in my code like this:

<input name="userSub" type="hidden" value={user.sub} />
<input name="email" type="hidden" value={user.email} />

This returns an error that User is possibly undefined, which I guess is because UserProfile could return undefined, so I add an ? to the user object like this:

<input name="userSub" type="hidden" value={user?.sub} />
<input name="email" type="hidden" value={user?.email} />

This fixes that error, but value has a red underline with the following error:

Type 'string | null | undefined' is not assignable to type 'string | number | readonly string[] | undefined'. Type 'null' is not assignable to type 'string | number | readonly string[] | undefined'.ts(2322)

In addition to this error:

The expected type comes from property 'value' which is declared here on type 'DetailedHTMLProps<InputHTMLAttributes, HTMLInputElement>'

If I add an ! to the property, the error goes away:

<input name="userSub" type="hidden" value={user?.sub!} />
<input name="email" type="hidden" value={user?.email!} />

It also works if I add as string:

<input name="userSub" type="hidden" value={user?.sub as string} />
<input name="email" type="hidden" value={user?.email as string} />

Why does this work and is it good practice to combine ? and ! like this? Should I avoid using ! altogether? I've read that type assertion with as is to be used with caution. I'm new in TS so greatly appreciate any explanations.

CodePudding user response:

These are both essentially different ways of handling values that are possibly null or undefined.
The main difference being that, with ? you are telling typescript that the value might be undefined, and that in such a case, it should simply return an undefined.
While with !, you are telling typescript that you know for sure that the property is neither a null nor an undefined.
as string basically does the same thing as ! in this case, where you are telling typescript that you know for sure the value is of type string.

Note that this is potentially dangerous, since if the value does end up being null or undefined, it could result in unwanted behavior.
As you can infer, this is a way to "silence" typescript, and therefor should only be used if you are sure that it is correct for your use-case.


Edit:

Here's additional information regarding ? - aka JavaScript's "optional-chaining operator".

And additional information regarding ! - aka TypeScript's "non-null assertion operator".

  • Related