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
类型。 undefined
与 null
不同。
根据此类型定义 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>());
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
类型。 undefined
与 null
不同。
根据此类型定义 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>());