打字稿:联合类型`string |未定义`和三元

Typescript: Union type `string | undefined` and ternary

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

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
}

感谢您的帮助:)

Doesn't the first return do the same kind of check ?

不,不是。有效的使用

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
Truthy Truthy Truthy Falsy Falsy
Truthy Falsy Falsy Truthy Falsy
Falsy Truthy Falsy Truthy Falsy
Falsy Falsy Falsy Truthy Truthy

要从布尔代数转换回代码,Falsy 值可能只是 undefined,如果 属性 从 member对象。

这意味着,例如,firstNamelastNameundefined,那么您所做的检查 returns 与您想要的相反:

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