Typescript函数返回类型null如果参数为null

Zen*_*tzi 3 types function typescript

我想让Typescript知道如果传递给函数的dbUser参数不为null,那么结果肯定不会为null.

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
Run Code Online (Sandbox Code Playgroud)

基本上,我确信如果dbUser参数不为null,结果也不会.如何以这种方式定义功能?目前,当我使用非null参数调用getUser函数时,它仍然表示结果可能为null,我知道肯定不能.

Tit*_*mir 8

有几种选择.您可以使用带有重载的函数声明:

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
Run Code Online (Sandbox Code Playgroud)

您还可以使用箭头功能和类型样式获得重载,但它们看起来更加丑陋:

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)
Run Code Online (Sandbox Code Playgroud)

您还可以使用条件类型:

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)
Run Code Online (Sandbox Code Playgroud)

我会推荐第一个选项,它是最干净的,不需要类型断言,不像其他两个.