打字稿:联合类型`string | undefined` 和三元

时间:2021-05-11 14:05:09

标签: typescript conditional-operator union-types

我对下面的代码有疑问,我不确定为什么第二次返回有效。第一次返回不是做同样的检查吗?

type User = {
  email: string
  firstName?: string
  lastName?: string
  first_name?: string
  last_name?: string
} & ({ first_name: string } | { firstName: string }) &
  ({ last_name: string } | { lastName: string })

const formatUserFullName = (firsname: string, lastname: string): string => `${firsname} ${lastname}`

export const computeUserFullName = (member: User): string => {
  let { firstName, lastName } = member
  if (!firstName) {
    firstName = member.first_name
  }
  if (!lastName) {
    lastName = member.last_name
  }

  // This throw an error about firstName and lastName that can be undefined and are not accepted by my method
  return !firstName && !lastName
    ? member.email
    : formatUserFullName(firstName, lastName)

  // This works
  return !!firstName && !!lastName
    ? formatUserFullName(firstName, lastName)
    : member.email
}

感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

<块引用>

第一次返回不是做同样的检查吗?

不,它没有。有效的使用

firstName && lastName

(简化,因为在布尔代数 !!x = x

和那个表达式的逆是

!(firstName && lastName)

根据 DeMorgan's law not (A and B) = not A or not B 转换为:

!firstName || !lastName

很容易检查这些真值表,看看哪个是产生相反结果的正确操作:

<头>
firstName lastName firstName && lastName !firstName || !lastName !firstName && !lastName
真实 真实 真实
真实 真实
真实 真实
真实 真实

要从布尔代数转换回代码,在 undefined 对象中缺少属性的情况下,Falsy 值可能只是 member

这意味着,例如,firstNamelastNameundefined,那么您所做的检查会返回与您想要的相反的结果:

const check1 = (firstName, lastName) => {
  // This works
  return !!firstName && !!lastName
}
const check2 = (firstName, lastName) => {
   // This throw an error about firstName and lastName that can be undefined and are not accepted by my method
 return !firstName && !lastName
}
console.log(
  check1("Fred", undefined),  //false - correct
  !check1("Fred", undefined), //true - expected
  check2("Fred", undefined)   //false - wrong
);
console.log(
  check1(undefined, "Bloggs"), //false - correct
  !check1(undefined, "Bloggs"),//true - expected
  check2(undefined, "Bloggs")  //false - wrong
);

这表明 TypeScript 正确地发现了代码中的错误。使用时正常运行

return !firstName || !lastName
    ? member.email
    : formatUserFullName(firstName, lastName)

Playground Link