I want to let Typescript know that if the dbUser parameter passed to the function is not null, then that the result will not be null for sure.
type GetUser = (dbUser: DbUser | null) => GqlUser | null;
const getUser: GetUser = (dbUser) => {
if(!dbUser) return null;
return ... //gql user
};
const dbUser = { ... some fields} //not null for sure
getUser(dbUser) //here I want typescript to know that the result will not be null
Basically, I know for sure that if dbUser parameter is not null, the result won't be either. How can I define the function in such a way? Currently, when I call the getUser function with non-null parameter, it still says that the result could be null, which I know for sure can't.
There are several options. You can use a function declaration with overloads:
function getUser(dbUser: null) : null;
function getUser(dbUser: DbUser) : GqlUser;
function getUser(dbUser: DbUser | null) : GqlUser | null;
function getUser(dbUser: DbUser | null): GqlUser | null {
if(!dbUser) return null;
return null! //gql user
}
const dbUser = null! as DbUser
getUser(dbUser) // GqlUser
You can also get overloads with the arrow function and type style but they look uglier:
type GetUser = {
(dbUser: null) : null;
(dbUser: DbUser) : GqlUser;
(dbUser: DbUser | null) : GqlUser | null;
}
const getUser = ((dbUser: DbUser | null): GqlUser | null => {
if(!dbUser) return null;
return null! //gql user
}) as GetUser
const dbUser = null! as DbUser
getUser(dbUser)
You could also use conditional types:
type GetUser = <T extends DbUser | null>(dbUser: T) => T extends DbUser ? GqlUser : null;
const getUser: GetUser = (dbUser) => {
if (!dbUser) return null;
return {} as any // assertions will be required to get a value into the conditioanl type
};
const dbUser = null! as DbUser //not null for sure
getUser(dbUser)
I would recommend the first option, it's the cleanest and requires not type assertions unlike the other two.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With