`<T extends E>` 形式的通用约束,其中`E` 是`enum`?

Posted

技术标签:

【中文标题】`<T extends E>` 形式的通用约束,其中`E` 是`enum`?【英文标题】:Generic constraint of the form `<T extends E>` where `E` is an `enum`? 【发布时间】:2021-01-17 16:28:09 【问题描述】:

类似这样的东西是什么意思:

function f<T extends E>(obj: T) 

E 是一些 enum 之类的,比如说

enum E 
    X

由于enums实际上无法扩展,所以不能删除这个约束并将函数重写为:

function f(obj: E) 

PS:this 是有问题的代码。

【问题讨论】:

【参考方案1】:

如果您的函数中不需要T 的类型,那么您是对的,不需要泛型。

但是,在您链接的文件中,类型在类中使用。

这里是相关的部分,其他的东西被删掉了:

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;
        //...
    

这表示将EditorOption 类型的id 传递给构造函数。这保存在通用类类型K1 中。稍后当您访问id 属性时,它将返回传递给构造函数的相同枚举选项。这需要泛型才能捕获枚举的子类型(该枚举的特定值),并在该函数的返回值或类的实例中使用它。


用你自己的例子来澄清一下:

function f1(arg: MyEnum):  id: MyEnum  
    return  id: arg 


const a1 = f1(MyEnum.A) // Type: MyEnum
const b1 = f1(MyEnum.B) // Type: MyEnum

当您在此处键入参数为MyEnum 时,您不能使用返回类型中提供的枚举,因此您最好将返回值键入为MyEnum,因为您不能知道提供了该枚举的哪个值。

但是当你使用泛型时:

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

现在您可以在返回类型中使用确切提供的参数类型。

这或多或少是您链接的代码在做什么。

Playground

【讨论】:

【参考方案2】:

如果一个类型扩展了一个枚举,则意味着该类型可以是:

枚举的一个特定值 枚举值的一些子集 枚举的所有可能值

假设我们的枚举有三个值:

enum E 
    X,
    Y,
    Z


function f<T extends E>(val: T) 

调用函数f时,一次只能传递一个E的值。但这并不意味着泛型T只能E 的一个值。如果手动指定泛型T,则所有这些都有效:

f<E>(E.X);
f<E.X>(E.X);
f<E.X | E.Y>(E.X);
f<Exclude<E, E.Y>>(E.X);

在任何情况下,E.X 都可以分配给 T(即,E.X 等于或小于 T)和 T extends E(即,T 等于或小于比E)。

Playground Link

【讨论】:

以上是关于`<T extends E>` 形式的通用约束,其中`E` 是`enum`?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA泛型<T>的使用,<? extends E>和<? super E>的含义

extend 和append

如何理解 Java 中的 lt;T extends Comparable<

java中泛型限定<? extends Comparable<? super T>> 和 <T extends Comparable<? super T>&g

java.lang.Enum<E extends Enum<E>>

为啥打字稿不能用 <T extends Person, K extends keyof T> generic 正确推断 T[K]?