解决回调定义错误:可分配给约束,但可以用不同的子类型实例化。 ( TS 2345 )

问题描述 投票:0回答:1

任何人都可以描述在下面的代码中造成编译器错误的类型问题的性质,并可能建议一种替代方法吗?

我相信我正确地约束了一个类型,但是一旦我依赖约束,我就会被告知可能会有一个不同的子类型飞来飞去,但我不明白为什么任何子类型都没有绑定到也满足约束我我依赖于(“艺术家”是其允许的值之一)。约束

extends "artist"
旨在实现这一目标。我不使用
TaleState<"artist">
,因为允许
TaleState
包括其他角色以及“艺术家”,但它必须有“艺术家”才能运行此逻辑。

错误内联在下面的代码中,在问题下进行了描述,并在Typescript Playground中可见。

export type Role = "artist" | "writer" | "maker";

export interface TaleState<TaleRole extends Role> {
  rolesVisited: Record<TaleRole, boolean>;
}

export function evidence<TaleRole extends Role, Evidenced extends TaleRole>(
  state: TaleState<TaleRole>,
  ...roles: [Evidenced, ...Evidenced[]]
) {
  for (const role of roles) {
    state.rolesVisited[role] = true;
  }
}

function artistTale<TaleRole extends "artist" >(
  state: TaleState<TaleRole>
) {
  /** the call below has a compiler error which reads...
   * Argument of type '"artist"' is not assignable to parameter of type 'Evidenced'.
   * '"artist"' is assignable to the constraint of type 'Evidenced', 
   * but 'Evidenced' could be instantiated with a different subtype of constraint '"artist"'
   */
  evidence(state, "artist");
}

问题

目前在 artistTale 函数中存在输入问题。我希望能够在任何角色中包含“艺术家”的 TaleState 上运行此功能。

读取

evidence(state, "artist");
的行有以下编译错误...

Argument of type '"artist"' is not assignable to parameter of type 'Evidenced'. '"artist"' is assignable to the constraint of type 'Evidenced', but 'Evidenced' could be instantiated with a different subtype of constraint '"artist"'

我正在努力了解

extends "artist"
在这里不是一个合适的约束。

我确定我的理解有一些根本性的倒退,但我很难看到是什么。可能我在推理

extends
如何表达文字的输入时有一个盲点,这让我陷入了这些困境。

我尝试了各种技巧来控制推理,以便类型由

state
值驱动,但我现在可能遇到了不同的困难。

问题

任何人都可以帮助我理解这可能是类型错误的方式吗?

我应该如何定义 artistTale - 一个允许我操纵适当约束的 TaleState 的函数(假设 Tale 包含我正在操纵的角色,使证据回调有效)。

背景

这个简化的错误示例来自投资组合 API。该项目通过讲述故事来展示角色。

故事类型限制了故事声明它将证明的角色。操纵状态的

evidence
回调(具有角色的自动完成)可以记录在故事期间何时证明角色。

既有

Evidenced
角色类型又传递
roles
运行时值是至关重要的(例如,拥有与故事关联的实际列表允许检查所有角色最终在故事的测试执行期间得到证明)。出于这个原因,API 是大量推理的。

typescript constraints inference subtype
1个回答
0
投票
function artistTale<T extends 'artist', E extends T>(
  state: TaleState<T>
) {
  evidence(state, 'artist' as E);
}
© www.soinside.com 2019 - 2024. All rights reserved.