让我们从代码开始TS Playground:
type Data = { [key: string]: Data } | string | number | boolean;
type ProtocolBlueprint = { args: Data[], result: Data };
type ProtocolDesc = { [key: string] : ProtocolBlueprint };
type MessageSender = number;
type AllowBeAsync<T> = Promise<T> | T;
type ProtocolListener<B extends ProtocolBlueprint> = (...args: [...B["args"], sender: MessageSender]) => AllowBeAsync<B["result"]>;
function registerInProtocol<D extends ProtocolDesc, K extends keyof D>(name: K, listener: ProtocolListener<D[K]>) : void
{
// ...
// I CAN'T CHANGE `implementation` TYPE FROM ProtocolListener<ProtocolBlueprint>` TO `ProtocolListener<D[K]>` IS MUST STAY MORE BROAD ABSTRACT TYPE.
const implementation: ProtocolListener<ProtocolBlueprint> = listener; // why this assignment is not valid? template paramter `D[K]` evaluates to `ProtocolBlueprint`.
console.log(implementation);
// ...
}
type Supported =
{
"countUsers": { args: [], result: number };
"doesUserExist": { args: [id: number], result: boolean };
}
registerInProtocol<Supported, "countUsers">("countUsers", () => { return 23 });
为什么我收到此错误消息:
类型“ProtocolListener
”不可分配给类型“ProtocolListener ”。
参数“args”和“args”的类型不兼容。
类型“[...Data[],发件人:number]”不可分配给类型“[...D[K][“args”],发件人:number]'。
源未提供与目标中位置 0 处的可变参数元素的匹配项。(2322)
我无法解释为什么会出现此错误,就像我在评论中提到的那样,
D[K]
计算为ProtocolBlueprint
,因此两种类型都应该匹配ProtocolListener<ProtocolBlueprint>
。在我的情况下,哪个变量是 Source
哪个 Target
(来自错误消息的最后一行)?