我对下面的代码有疑问,我不确定为什么第二次返回有效。第一次返回不是做同样的检查吗?
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
}
感谢您的帮助:)
答案 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
。
这意味着,例如,firstName
或 lastName
是 undefined
,那么您所做的检查会返回与您想要的相反的结果:
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)