`mixed` 和 `any` 有什么区别?

What is the difference between `mixed` and `any`?

docs 说:

  • mixed: the "supertype" of all types. Any type can flow into a mixed.
  • any: the "dynamic" type. Any type can flow into any, and vice-versa

mixedany 不能互换使用的情况是什么?

区别在于“反之亦然”: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]"

来自您链接到的文档:

It is worth calling out any specifically because of the special nature of this annotation. Use any to escape the static typing of Flow. In other words, if Flow is getting in your way, and you are absolutely convinced your program is type correct, you can silence the errors by annotating locations along the error paths with type any.

"Any"支持协变和逆变。那是因为 "any" 是所有类型的超类型和子类型。

因此这有效,

let genericVariable: any = 20;
let numericVariable: number;

genericVariable = numericVariable; // No error
numericVariable = genericVariable; // No error

mixed 仅支持协方差。它是超类型,不是所有类型的子类型。

let genericVariable: mixed = 20;
let numericVariable: number;

numericVariable = genericVariable; // This shows error
genericVariable = numericVariable; // This works fine.

协方差 - 通用类型(父)可以被特殊类型(子)替代

逆变 - 特殊类型(子)可以替换为通用类型(父)。这是一个问题,除非受到某些约定的保护。

当流看到 any 时,这意味着您可以使用任何类型。该程序对参数的类型无动于衷,也不会尝试推断结果类型。因此结果类型也将是 any

例如下面的代码不会报错:

// @flow
function add(one: any, two: any): number {
  return one + two;
}

add(1, 2);     // Works.
add("1", "2"); // Works.
add({}, []);   // Works.

但是 "mixed" 应该以某种方式处理类型以推断实际类型。

// @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");