TypeScript规范在§4.15.6中说明了&&运算符:
&&运算符允许操作数为任何类型,并产生与第二个操作数相同类型的结果.
在Javascript中,&&运算符返回第一个操作数(如果它是假的),否则它返回第二个操作数(参见ECMA-262§11.11).
这意味着如果左操作数是假的,&&将返回一个与左操作数的类型匹配的值.例如,
typeof ( false && {} ) === "boolean" // true
typeof ( '' && 1 ) === "string" // true
typeof ( null && "hello" ) === "object" // true
typeof ( NaN && true ) === "number" // true
Run Code Online (Sandbox Code Playgroud)
打字稿,根据上面引述的规则,将不正确地预测的类型上面的表达式的是Object,Number,String和Boolean,分别.
我错过了什么吗?是否有充分的理由使&&表达式的类型与第二个操作数的类型相匹配?结果类型不应该像||运算符一样,并返回两个操作数的最佳公共类型,Any如果没有最佳公共类型?
Rya*_*ugh 25
长话短说,这里没有解决方案让大家高兴.
考虑这个常见的习语:
var customer = GetCustomer(...); // of type 'Customer'
var address = customer && customer.address;
if(address) {
printAddressLabel(address); // Signature: (Address) => void
} else {
// Couldn't find the customer or the customer has no address on file
}
Run Code Online (Sandbox Code Playgroud)
放弃并决定'地址'是'任何'是非常蹩脚的,因为客户和地址之间没有最佳的共同类型.
在使用&&运算符的大多数情况下,类型已经匹配,或者&&正在以类似于上面的值合并方式使用.在任何一种情况下,返回右操作数的类型都会为用户提供预期的类型.
虽然此时类型安全在技术上已经崩溃,但它并没有以可能导致错误的方式进行.您要么测试结果值的真实性(在这种情况下类型或多或少不相关),或者您将使用假定的右操作数进行某些操作(上面的示例同时执行这两个操作).
如果我们看一下你列出的例子,并假装左操作数是不确定的truthy或falsy,然后尝试编写对返回值进行操作的合理代码,它会变得更加清晰 - 你可以用'false && 做多少{}'尚未进入'任何'参数位置或真实性测试.
附录
由于有些人不相信上述内容,这里有不同的解释.
让我们假装的打字稿类型系统增加了三种新类型的一个时刻:Truthy<T>,Falsy<T>,和Maybe<T>,代表类型的可能truthy/falsy值T.这些类型的规则如下:
Truthy<T> 表现得很像 TFalsy<T>Maybe<T>,作为条件在使用时if块,成为Truthy<T>在同一的主体if块和Falsy<T>在else块这可以让你做这样的事情:
function fn(x: Maybe<Customer>) {
if(x) {
console.log(x.address); // OK
} else {
console.log(x.phone); // Error: x is definitely falsy
}
console.log(x.name); // Warning: x might be falsy!
}
Run Code Online (Sandbox Code Playgroud)
到目前为止相当不错.现在我们可以弄清楚&&运算符的类型规则是什么.
Truthy<T> && x 应该是一个错误 - 如果左侧被认为是真的,你应该写的 xFalsy<T> && x应该是一个错误 - 如果已知左侧是假的,x则是无法访问的代码Maybe<T> && x 应该产生什么?我们知道结果Maybe<T> && x将是类型的假值T,或者x.它不能产生Truthy<T>(除非T= = x在这种情况下整个讨论都没有实际意义的类型).我们称之为新类型Falsy<T> XOR Maybe<U>.
规则应该Falsy<T> XOR Maybe<U>是什么?
T它的属性.如果值是类型T,它是假的,并且不安全使用.Maybe<U>,因为Falsy<T>并Falsy<U>具有相同的行为U,因为值仍然可能是假的.if测试中使用它,那么它应该成为Truthy<U>该if语句的块换句话说,Falsy<T> XOR Maybe<U> 是 Maybe<U>.它遵循所有相同的规则.通过添加这种奇怪的XOR类型,您根本不需要使类型系统复杂化,因为适合您所需的所有规范的类型已经存在.
这有点像给某人一个盒子并说"这可能是一个空盒子的垃圾,也可能是一整箱可回收物品".您可以安全地将盒子的内容清空到回收站中.
| 归档时间: |
|
| 查看次数: |
9345 次 |
| 最近记录: |