How @TypeOf chooses the resulting type when there are more than one arguments

The following program, prints:

> zig run typeof.zig
a:comptime_int b:u8 T:u8

> cat typeof.zig
const std = @import("std");

fn foo(a: anytype, b: anytype) void {
    const T = @TypeOf(a, b);
    std.debug.print("a:{s} b:{s} T:{s}\n", .{

pub fn main() void {
    const v: u8 = 'a';
    foo(32, v);

In master testing.zig expectEqual is declared as:

pub inline fn expectEqual(expected: anytype, actual: anytype) !void {
    const T = @TypeOf(expected, actual);

In 0.11.0 testing.zig expectEqual is declared as:

pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void {

A headache with expectEqual is gone, but how @TypeOf selects the resulting type?

1 Like

Language Reference: @TypeOf

@TypeOf is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using Peer Type Resolution.

Peer Type Resolution:

This kind of type resolution chooses a type that all peer types can coerce into.

I think there may be more to explain and explore in detail here, that is just the first few things I found.