Skip to main content

Mixed

mixed is the supertype of all types. All values are mixed. However, this means that very few operations are permitted on it, without refining to some more specific type. That's because the valid operations on mixed must be valid for all types.

In general, programs have several different categories of types:

A single type:

Here the input value can only be a number.

1function square(n: number) {2  return n * n;3}

A group of different possible types:

Here the input value could be either a string or a number.

1function stringifyBasicValue(value: string | number) {2  return '' + value;3}

A type based on another type:

Here the return type will be the same as the type of whatever value is passed into the function.

1function identity<T>(value: T): T {2  return value;3}

These three are the most common categories of types. They will make up the majority of the types you'll be writing.

However, there is also a fourth category.

An arbitrary type that could be anything:

Here the passed in value is an unknown type, it could be any type and the function would still work.

1function getTypeOf(value: mixed): string {2  return typeof value;3}

These unknown types are less common, but are still useful at times.

You should represent these values with mixed.

Anything goes in, Nothing comes out

mixed will accept any type of value. Strings, numbers, objects, functions– anything will work.

1function stringify(value: mixed) {2  // ...3}4
5stringify("foo");6stringify(3.14);7stringify(null);8stringify({});

When you try to use a value of a mixed type you must first figure out what the actual type is or you'll end up with an error.

1function stringify(value: mixed) {2  return "" + value; // Error!
3}4 5stringify("foo");
2:10-2:19: Cannot use operator `+` with operands string [1] and mixed [2] [unsafe-addition]

Instead you must ensure the value is a certain type by refining it.

1function stringify(value: mixed) {2  if (typeof value === 'string') {3    return "" + value; // Works!4  } else {5    return "";6  }7}8
9stringify("foo");

Because of the typeof value === 'string' check, Flow knows the value can only be a string inside of the if statement. This is known as a refinement.

Versus any

mixed is safe, while any is not. Both accept all values, but any also unsafely allows all operations.

Versus empty

mixed is the opposite of empty:

  • Everything is a mixed, but few operations are permitted on it without first refining to a specific type. It is the supertype of all types.
  • Nothing is empty, but any operation is permitted on it. It is the subtype of all types.