文档说:
mixed
:所有类型的“超类型”。任何类型都可以流入一个mixed
.any
:“动态”类型。任何类型都可以流入any
,反之亦然
什么情况下mixed
不能any
互换使用?
不同之处在于“反之亦然”:any
可以流入其他类型但mixed
不能。
/* @flow */
var numeric:number = 0;
var anyTyped:any;
var mixTyped:mixed;
numeric = anyTyped;
numeric = mixTyped; // This will throw a flow check error: "Cannot assign `mixTyped` to `numeric` because mixed is incompatible with number. [incompatible-type]"
从您链接到的文档中:
由于此注释的特殊性,值得特别指出任何内容。使用 any 来转义 Flow 的静态类型。换句话说,如果 Flow 妨碍了您,并且您完全确信您的程序类型正确,您可以通过使用 any 类型注释错误路径上的位置来消除错误。
“任何”支持协变和逆变。那是因为“any”是所有类型的超类型和子类型。
因此,这有效,
let genericVariable: any = 20;
let numericVariable: number;
genericVariable = numericVariable; // No error
numericVariable = genericVariable; // No error
混合仅支持协方差。它是超类型,而不是所有类型的子类型。
let genericVariable: mixed = 20;
let numericVariable: number;
numericVariable = genericVariable; // This shows error
genericVariable = numericVariable; // This works fine.
协方差 - 通用类型(父)可以被特殊类型(子)替换
逆变 - 特殊类型(子)可以替换为通用类型(父)。这是一个问题,除非受到某些约定的保护。
当 flow 看到any
这意味着你可以使用任何类型。程序对参数的类型无所谓,不会尝试推断结果类型。所以结果类型any
也是。
例如下面的代码不会报任何错误:
// @flow
function add(one: any, two: any): number {
return one + two;
}
add(1, 2); // Works.
add("1", "2"); // Works.
add({}, []); // Works.
但是应该以某种方式处理“混合”类型以推断实际类型。
// @flow
function stringify(value: mixed) {
// $ExpectError
return "" + value; // Error!
}
stringify("foo");
相反,您必须通过改进它来确保该值是某种类型。
// @flow
function stringify(value: mixed) {
if (typeof value === 'string') {
return "" + value; // Works!
} else {
return "";
}
}
stringify("foo");