TypeScript 泛型错误(对 `?super T` 使用 `Partial<T>`)

Error with TypeScript Generics (Using `Partial<T>` for `? super T`)

TypeScript 编译失败,因为我无法解释与泛型相关的错误。我创建了一个最小的例子:

interface Processor<T> { process(data:T):void; }
class ArrayProcessor<T> implements Processor<Array<T>|null> { process(data:Array<T>|null):void {} }
  // intention (Java syntax, TS?): ... `implements Processor<List<? extends T>/*|null*/>` ...
const applyProcessor = <T,>(processor:Processor<Partial<T>>) => {};
  // intention (Java syntax, TS?): ... `<T> void applyProcessor(Processor<? super T> processor)` ...

applyProcessor<Array<number>>(new ArrayProcessor<number>());
//                      ERROR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

最后一行产生错误消息:

Argument of type 'ArrayProcessor<number>' is not assignable to parameter of type 'Processor<(number | undefined)[]>'.
  Types of property 'process' are incompatible.
    Type '(data: number[] | null) => void' is not assignable to type '(data: (number | undefined)[]) => void'.
      Types of parameters 'data' and 'data' are incompatible.
        Type '(number | undefined)[]' is not assignable to type 'number[]'.
          Type 'number | undefined' is not assignable to type 'number'.
            Type 'undefined' is not assignable to type 'number'.(2345)

我试图调查 TypeScript 认为什么是可分配的。 |null 部分可能对这里有影响:

const myArg1:Processor<Partial<Array<number>|null>> = new ArrayProcessor<number>(); // <- No error
const myArg2:Processor<Partial<Array<number>>> = new ArrayProcessor<number>(); // <- ERROR
// Type 'ArrayProcessor<number>' is not assignable to type 'Processor<(number | undefined)[]>'.(2322)

为什么 applyProcessor 调用失败?错误消息中的这些 undefined 是从哪里来的?如何修复第一个片段?

额外问题:TypeScript 是否有等同于 Java 的 <? super T>?我很乐意声明我的意图(“...是处理器/比较器/消费者/处理程序/...的...”),即使 TypeScript 编译器实际上无法强制执行约束,也不会出现编译错误。

问题出在Partial.

当您使用 Partial 和显式 number 通用参数 new ArrayProcessor<number>() 时,它会导致错误,因为 Partial 应用 undefined 类型。 undefinednull 不同。

根据此类型定义 implements Processor<Array<T> | null 您期望 Processor 泛型的数组或空值,而 Processor<Partial<T>> 意味着您期望 smth 不同。

为了修复它,你可以重写applyProcessor函数:

const applyProcessor = <T,>(processor: Processor<T | null>) => { };

const applyProcessor = <T,>(processor: Processor<T>) => { };

完整代码:

interface Processor<T> {
  process(data: T): void;
}

class ArrayProcessor<T> implements Processor<Array<T> | null> {
  process(data: Array<T> | null) { }
}

const applyProcessor = <T,>(processor: Processor<T|null>) => { };

applyProcessor(new ArrayProcessor<number>());