Vladislav Khazipov
Vladislav Khazipov

Reputation: 333

Why conditional type with any works differently?

The question is pretty simple, why in this situation type s is a union of both variables.

type s = any extends boolean ? 'Yes' : 'no';

It seems logical that any type can literally be anything but is there a better explanation of this behaviour?

Upvotes: 1

Views: 84

Answers (1)

jcalz
jcalz

Reputation: 328272

I could give my opinion for why this is the case, but that's not really what you're asking for, I gather.

The only canonical explanation for why this behavior happens that I can find is from the comment in lines #13287 through #13290 of checker.ts where it's implemented (you can't directly view files that large on GitHub 🤷‍♂️):

// Return union of trueType and falseType for 'any' since it matches anything
if (checkType.flags & TypeFlags.Any) {
  (extraTypes || (extraTypes = [])).push(
    instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper)
  );
}

All other references I can find to this behavior just confirm that it is that way, not why. For example, microsoft/TypeScript#27418 asks what conditional types where the checked type is unknown should evaluate to, and mentions: "to add to the confusion, any also has its own wildcard behavior that matches both branches". In this case, unknown extends X ? T : F will only return T if X is unknown, and F otherwise; it never returns T | F. 🤔

So the closest to an authoritative answer I can see here is because the implementer said "any matches anything, so return the union of both branches". Oh well, hope that helps; good luck!

Upvotes: 2

Related Questions