# Type Aliases: Transparent

A transparent type alias is one created using `type`.

```<?hh
type UserIDtoFriendIDsMap = Map<int, Vector<int>>;
```

For a given type, that type and all transparent aliases to that type are all the same type, and can be freely interchanged -- they are completely equivalent in all respects. There are no restrictions on where a transparent type alias can be defined or which source code can access its underlying implementation.

Unlike opaque type aliases, since nothing distinguishes between the alias and the aliased type, transparent type aliases aren't particularly useful as an abstraction mechanism. Their primary use case is in defining a shorthand type name increase readability and to save typing. Consider the following function signature, and how much more cumbersome it would be without the `Matrix` type alias:

```<?hh

namespace Hack\UserDocumentation\TypeAliases\Transparent\Examples\Converted;

type Matrix<T> = Vector<Vector<T>>;

function add<T as num>(Matrix<T> \$m1, Matrix<T> \$m2): Matrix<num> {
// Assumes that \$m1 and \$m2 have the same dimensions; real code should have
// better error detection and handling of course.
\$r = Vector {};
foreach (\$m1 as \$i => \$row1) {
\$new_row = Vector {};
foreach (\$row1 as \$j => \$val1) {
\$new_row[] = \$val1 + \$m2[\$i][\$j];
}
\$r[] = \$new_row;
}

return \$r;
}

function get_m1(): Matrix<int> {
// No conversion needed from these Vectors into the Matrix return type, since
// the two are equivalent.
return Vector { Vector { 1, 2 }, Vector { 3, 4 } };
}

function get_m2(): Vector<Vector<int>> {
return Vector { Vector { 5, 6 }, Vector { 7, 8 } };
}

function run(): void {
get_m1(),
// get_m2() returns a Vector<Vector<int>>, and add() takes a Matrix<int>,
// but no conversion is needed here since the two are equivalent.
get_m2()
));
}

run();
```
Output
```object(HH\Vector)#7 (2) {
[0]=>
object(HH\Vector)#8 (2) {
[0]=>
int(6)
[1]=>
int(8)
}
[1]=>
object(HH\Vector)#9 (2) {
[0]=>
int(10)
[1]=>
int(12)
}
}
```