1

I understand that NonNullable is meant to remove null and undefined as valid values for a type, but it seems it is not working as expected.

I have the following code:

interface User {
    name: string;
}


type NonNullableUser = NonNullable<User>;
let user1 : NonNullable<User> = { name: "foo"}
let user2 : NonNullable<User> = null // expect this to lead to a type error

I expect let user2 : NonNullable<User> = null to not compile but it still does! Note, I set the strictNullChecks to off, because if I set it to on, the compiler automatically prevents null assignment and let user2: User = null would lead to a compile error removing the need for the utility type NonNullable.

If I need to have strictNullChecks on for this work, then I wonder if NonNullable is not redundant then?

Or perhaps I do not get how to make use of NonNullable? Any thoughts?

0

2 Answers 2

3

Note, I set the strictNullChecks to off, because if I set it to on, the compiler automatically prevents null assignment and let user2: User = null would lead to a compile error

This is your problem. With strictNullChecks off, null and undefined are assignable to everything. With it on they are only assignable to types that are explicitly typed as null or undefined. It is generally recommended to always have strictNullChecks on if you can.

removing the need for the utility type NonNullable.

That's not the case. With strictNullChecks on you can still explicitly specify that a type is nullable, and NonNullable will remove null/undefined from the type.

e.g.

interface User {
    name: string;
}

type NullableUser = User | null;

const user1: NullableUser = null;

type NonNullableUser = NonNullable<NullableUser>;

const user2: NonNullableUser = null; // Type error
Sign up to request clarification or add additional context in comments.

4 Comments

so if I get it, NonNullable is used to remove null | undefined from types you explicitly create to have null | undefined? Sounds not very useful to me. or perhaps I am not imaginative enough to see where this could be useful :/
I mean why not just have User and NullableUser types?
It's a contrived example just to illustrate how it works. Remember that not all code in your program is going to be written by you. You might be importing code from a third party library with a nullable type and want to convert it to non-nullable.
I guess. Thanks all the same. I think the part I was missing was understanding that this applies only to union types. Now I need to be more imaginative so think of the scenario where this would be useful :) Thanks!
3

The NonNullable utility type doesn't operate on object properties but on the object type itself.

We could introduce a custom utility type to exclude null and undefined from all properties of the object:

type NonNullableValues<T> = {
  [P in keyof T]: NonNullable<T[P]>;
};

interface User {
    name: string | null;
}

type NullableUser = NonNullableValues<User>;
// type NullableUser = { name: string }

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.