The underlying issue here is not specific to enums. It happens whenever you return a value of a single literal type from a function instead of a union of such types. For example, here is the analogous behavior for string literals:
function foo() { return "a"; }
// function foo(): string
function bar() { return Math.random() < 0.5 ? "a" : "z" };
// function bar(): "a" | "z"
The compiler uses heuristics to determine whether or not to widen a literal to its base type, based on assumptions of what behavior would most accurately conform to the expectations and desires of developers of real world code. These rules are described in microsoft/TypeScript#10676, the PR that implemented this functionality.
For example, compare the inferred types in the following lines:
const x = "a"; // const x: "a"
let y = "a"; // let y: string
Here the type of x is inferred as the string literal type "a", while the type of y is widened from "a" to string. The reasoning behind this difference is that you can't change the value of a const variable, but you can change the value of a let variable. The assumption is that the author of this code probably intends to change the value of y to some other string, otherwise they would have used const.
Of course heuristics are just heuristics; and they sometimes get things wrong. When the compiler's inference rules do something you don't like, your recourse is to express your intent explicitly, such as with a type annotation:
let z: "a" = "a"; // let z: "a"
Anyway, the specific situation you've run into is described in this comment. The compiler assumes that few people intentionally write functions that return a single literal type. A function implementation that always returns "a" or Fruits.Apple might plausibly be modified in the future to return a different string value or a different Fruit value... otherwise the author probably wouldn't have bothered making this a function in the first place. So the return type is widened. But if a function implementation returns a union of literal values, it's more likely that the author would be happy with the narrower type.
Again, this isn't always what people want, but is apparently close enough that it broke the least amount of real world code when this functionality was introduced. If you are unhappy with it, your recourse is again to be more explicit, such as with a return type annotation:
function baz(): "a" {
return "a";
}
Playground link to code