If you don't need the type of T in your function, then you are right is doesn't need to be generic.
However, in the file you linked the type is used within the class.
Here's the relevant bits, with other stuff trimmed away:
abstract class ComputedEditorOption<K1 extends EditorOption, V> implements IEditorOption<K1, V> {
public readonly id: K1;
constructor(id: K1, deps: EditorOption[] | null = null) {
this.id = id;
//...
}
}
This says that an id of type EditorOption is passed to the constructor. This is saved in the generic class type K1. Later when you access the id property, it will return the same enum option that was passed to the constructor. This requires generics in order to capture a subtype of an enum (a specific value of that enum), and use it in the return value of that function, or the instance of a class.
To clarify with your own example:
function f1(arg: MyEnum): { id: MyEnum } {
return { id: arg }
}
const a1 = f1(MyEnum.A) // Type: MyEnum
const b1 = f1(MyEnum.B) // Type: MyEnum
When you type the argument as MyEnum here, you can't use the enum that was provided in the return type, so the best you can do is type the return value as MyEnum, because you can't know which value of that enum was provided.
But when you use a generic:
function f2<T extends MyEnum>(arg: T): { id: T } {
return { id: arg }
}
const a2 = f2(MyEnum.A) // Type: MyEnum.A
const b2 = f2(MyEnum.B) // Type: MyEnum.B
Now you can use the exactly provided type of the argument in the return type.
This is, more or less, what the code you linked is doing.
Playground