简体   繁体   English

TypeScript Generics 问题:类型 T(扩展类型)不可分配给 T

[英]TypeScript Generics problem: type T (extends Type) is not assignable to T

I have a problem with TypeScript generics in Deno.我对 Deno 中的 TypeScript generics 有疑问。

abstract class Packet {
    public abstract read(): Uint8Array;
    public abstract write(data: Uint8Array): void;
}

type PacketData = Packet | Uint8Array;
type HookCallbackResult<T extends PacketData> = T | null | undefined;
type HookCallback<T extends PacketData> = (data: T) => HookCallbackResult<T>;

interface HookCallbackInfo<T extends PacketData> {
    packetType: typeof Packet | "any";
    callback: HookCallback<T>;
}

let callbacks: HookCallbackInfo<PacketData>[] = [];

function hook<T extends PacketData>(packetType: typeof Packet | "any", callback: HookCallback<T>) {
    callbacks.push({ packetType, callback });
    //                           ^^^^^^^^
    // error: TS2322 [ERROR]: Type 'HookCallback<T>' is not assignable to type 'HookCallback<PacketData>'.
    // Types of parameters 'data' and 'data' are incompatible.
    //     Type 'PacketData' is not assignable to type 'T'.
    //     'PacketData' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'PacketData'.
    //         Type 'Packet' is not assignable to type 'T'.
    //         'Packet' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'PacketData'.
}

My purpose is to force a callback which is passed as 2nd argument to hook function to return a result of the same type as its argument OR null OR undefined and this type should be Uint8Array or already parsed Packet (or its child class) and nothing else.我的目的是强制回调作为第二个参数传递给hook function 以返回与其参数或nullundefined相同类型的结果,并且此类型应为Uint8Array或已解析的Packet (或其子类),仅此而已. And hook function should store this hook callback for further use.并且hook function 应该存储这个钩子回调以供进一步使用。 Deno's version of TypeScript compiler panics on adding a callback to an object (declared with interface HookCallbackInfo ) array. Deno 的 TypeScript 编译器版本在向 object(使用接口HookCallbackInfo声明)数组添加回调时出现恐慌。

I guess I made a mistake somewhere with generics cause I don't understand properly how they work in TypeScript with these multiple type definitions (like Type1 | Type2 | Type3 ).我想我在 generics 的某个地方犯了一个错误,因为我不明白它们如何在 TypeScript 中使用这些多种类型定义(如Type1 | Type2 | Type3 )。 Could you pls explain me what exactly I did wrong and how to do what I want in the proper way?你能解释一下我到底做错了什么以及如何以正确的方式做我想做的事吗?

Your callbacks array is an array of HookCallbackInfo<PacketData> values, which means their callback fields must contain functions of type (data: PacketData) => HookCallbackResult<PacketData> .您的callbacks数组是HookCallbackInfo<PacketData>值的数组,这意味着它们的callback字段必须包含(data: PacketData) => HookCallbackResult<PacketData>类型的函数。 In your hook function, you're passing in callbacks of some unknown type T that extends PacketData , so the callback you're trying to provide is a function of type (data: T) => HookCallbackResult<T> .在你的hook function 中,你传入了一些未知类型T的回调,它扩展PacketData ,所以你试图提供的回调是一个 function 类型(data: T) => HookCallbackResult<T>

This is where the problem lies: callbacks needs functions that can be called on any PacketData value, whereas you're trying to provide it with callbacks that can only be called on some PacketData values.这就是问题所在: callbacks需要可以在任何PacketData 值上调用的函数,而您试图为它提供只能在某些PacketData 值上调用的回调。 The type system detects and prevents you from doing so.类型系统会检测并阻止您这样做。

To see why this matters, consider what could go wrong if the type system didn't check this:要了解为什么这很重要,请考虑如果类型系统没有检查,go 会出现什么错误:

const myFn: (v: Packet) => null = ...
hook<Packet>("any", myFn);

const array: Uint8Array = ...
callbacks[0](array);  // we've called myFn with the wrong argument type!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 打字稿泛型:不可分配给T型 - Typescript generics : not assignable to type T TypeScript泛型:“类型不可分配给类型T” - TypeScript Generics: 'type is not assignable to type T' 类型&#39;T&#39;不能分配给&#39;T extends T? Type:中的T:T&#39; - Type 'T' is not assignable to type 'T extends T ? T : T' in TypeScript TypeScript泛型类型“ {result:true}”不能分配给类型“ T” - TypeScript Generics type '{ result: true }' is not assignable to type 'T' 打字稿泛型:类型“ X”的参数不能分配给类型“ T”的参数 - Typescript generics: Argument of type 'X' is not assignable to parameter of type 'T' 泛型:TS2345类型“ T [keyof T]”的参数不能分配给类型“ Date”的参数,其中<T extends {}> - Generics: TS2345 Argument of type 'T[keyof T]' is not assignable to parameter of type 'Date' where <T extends {}> TypeScript泛型:泛型函数类型和对象文字类型的调用签名不相等(类型&#39;T&#39;不能分配给类型&#39;T&#39;) - TypeScript generics: Inequivalence of generic function type and call signature of an object literal type (Type 'T' is not assignable to type 'T') Typescript generics 和字符串文字类型:“OnBlur”类型的参数不可分配给“T”类型的参数 - Typescript generics and String Literal Types: Argument of type “OnBlur” is not assignable to parameter of type “T” 打字稿编译错误:类型“ {}”不可分配给类型“ T” - Typescript Compile Error: Type '{}' is not assignable to type 'T' 打字稿类型“未定义”不能分配给类型“T” - Typescript Type 'undefined' is not assignable to type 'T'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM