Typescript Map< enum,set< enum>>“没有超载匹配此调用",但我不明白为什么? [英] Typescript Map<enum, set<enum>> "No overload matches this call", but I don't get why?

查看:36
本文介绍了Typescript Map< enum,set< enum>>“没有超载匹配此调用",但我不明白为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Typescript创建棋盘游戏.在其中声明以下内容:

I am creating a boardgame in Typescript. In it I declare the following:

export enum PieceType {
    PAWN,
    KNIGHT2,
    KNIGHT4,
    WIZARD,
    KING
}

export class Board {
    // ...
    private takeRules: Map<PieceType, Set<PieceType>> = new Map([
        [PieceType.PAWN, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD])],
        [PieceType.KNIGHT2, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD, PieceType.KING])],
        [PieceType.KNIGHT4, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD, PieceType.KING])],
        [PieceType.KING, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4])]
    ]);
    private enchantRules: Map<PieceType, Set<PieceType>> = new Map([
        [PieceType.WIZARD, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4])],
        [PieceType.KING, new Set([PieceType.WIZARD])]
    ]);
    // ...
}

此错误如下:

[tsl] ERROR in ./src/board.ts(28,60)
      TS2769: No overload matches this call.
  Overload 1 of 3, '(iterable: Iterable<readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>]>): Map<PieceType.WIZARD | PieceType.KING, Set<...>>', gave the following error.
    Argument of type '([PieceType.WIZARD, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>] | [PieceType.KING, Set<PieceType.WIZARD>])[]' is not assignable to parameter of type 'Iterable<readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>]>'.
      The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
        Type 'IteratorResult<[PieceType.WIZARD, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>] | [PieceType.KING, Set<PieceType.WIZARD>], any>' is not assignable to type 'IteratorResult<readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>], any>'.
          Type 'IteratorYieldResult<[PieceType.WIZARD, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>] | [PieceType.KING, Set<PieceType.WIZARD>]>' is not assignable to type 'IteratorResult<readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>], any>'.
            Type 'IteratorYieldResult<[PieceType.WIZARD, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>] | [PieceType.KING, Set<PieceType.WIZARD>]>' is not assignable to type 'IteratorYieldResult<readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>]>'.
              Type '[PieceType.WIZARD, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>] | [PieceType.KING, Set<PieceType.WIZARD>]' is not assignable to type 'readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>]'.
                Type '[PieceType.KING, Set<PieceType.WIZARD>]' is not assignable to type 'readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>]'.
                  Types of property '1' are incompatible.
                    Type 'Set<PieceType.WIZARD>' is not assignable to type 'Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>'.
                      Type 'PieceType.WIZARD' is not assignable to type 'PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4'.
  Overload 2 of 3, '(entries?: readonly (readonly [PieceType.WIZARD | PieceType.KING, Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>])[]): Map<PieceType.WIZARD | PieceType.KING, Set<...>>', gave the following error.
    Type 'Set<PieceType.WIZARD>' is not assignable to type 'Set<PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4>'.

如果我将第二张地图放在注释中:没问题.如果我省略第二张地图的最后一行中的向导枚举:没问题.我什至可以毫不费力地将省略的值用于构造函数中.例如

If I put the second map in comments: no problem. If I ommit the wizard enum in the last line of the second map: no problem. I can even put the ommitted value in using the constructor without a problem. E.g.

    private takeRules: Map<PieceType, Set<PieceType>> = new Map([
        [PieceType.PAWN, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD])],
        [PieceType.KNIGHT2, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD, PieceType.KING])],
        [PieceType.KNIGHT4, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD, PieceType.KING])],
        [PieceType.KING, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4])]
    ]);
    private enchantRules: Map<PieceType, Set<PieceType>> = new Map([
        [PieceType.WIZARD, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4])],
        [PieceType.KING, new Set([])]
    ]);

   // ...

    constructor() {
        // ...
        this.enchantRules.get(PieceType.KING).add(PieceType.WIZARD)
    }

我真的不明白这怎么可能?

I really don't understand how this is possible?

推荐答案

非常有趣的问题.这是解决方法:

Very interesting question. Here is solution:

export enum PieceType {
    PAWN,
    KNIGHT2,
    KNIGHT4,
    WIZARD,
    KING
}

export class Board {
    // ...
    private takeRules = new Map<PieceType, Set<PieceType>>([
        [PieceType.PAWN, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD])],
        [PieceType.KNIGHT2, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD, PieceType.KING])],
        [PieceType.KNIGHT4, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4, PieceType.WIZARD, PieceType.KING])],
        [PieceType.KING, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4])]
    ]);
    private enchantRules = new Map<PieceType, Set<PieceType>>([
        [PieceType.WIZARD, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4])],
        [PieceType.KING, new Set([PieceType.WIZARD])]
    ])
}

我只是为 Map 定义了泛型,而不是定义整个类型: new Map< PieceType,Set< PieceType>> .

I just defined generics for Map instead of defining whole type : new Map<PieceType, Set<PieceType>>.

但主要问题是,为什么会发生错误?

But main question, why the error occured?

让我们分析一下:

   private enchantRules: Map<PieceType, Set<PieceType>> = new Map([
        [PieceType.WIZARD, new Set([PieceType.PAWN, PieceType.KNIGHT2, PieceType.KNIGHT4])],
        [PieceType.KING, new Set([PieceType.WIZARD])]
    ]);

如果将类型定义 Map< PieceType,Set< PieceType>> 放在 equal 符号之前,TS将尝试推断这些类型.因此,如果您放置一些 PieceType 枚举值(该值在先前的实体中不存在),则会引发错误.

If you put type definition Map<PieceType, Set<PieceType>> before equal sign, TS will try to infer these type. Hence, if you put some PieceType enum value, which don't exists in previous entity, it will throw an error.

看一个简单的例子:

type Fst = PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4
type Scd = PieceType.WIZARD

let fst: Fst = PieceType.PAWN;
let scd: Scd = PieceType.WIZARD;

scd = fst; // error

您不能将 fst 分配给 scd ,但是,如果您将 PAWN 枚举类型添加到 Scd 类型,它将起作用:

You can't assign fst to scd, but, if you add PAWN enum type to Scd type, it will work:

type Fst = PieceType.PAWN | PieceType.KNIGHT2 | PieceType.KNIGHT4
type Scd = PieceType.WIZARD | PieceType.PAWN

let fst: Fst = PieceType.PAWN;
let scd: Scd = PieceType.WIZARD;

scd = fst; // ok

让我们回到我们的问题上来.因为在第一个映射值 V 中未定义 WIZARD ,所以根本无法使用WIZARD.

Let's go back to our problem. Because WIZARD was not defined in first Map value V, you are unable to use WIZARD at all.

所以,我相信您应该坚持使用显式泛型类型定义,而不是直接在变量定义附近定义类型.

SO, I believe you should stick with explicit generic type definition instead of defininf your type directly near variable definition.

P.S.您可能会发现

P.S. You may find this answer also interesting

我愿意接受批评,所以请随时指出我的错误.谢谢

I'm open to criticizm, so feel free to point my mistakes. Thanks

这篇关于Typescript Map&lt; enum,set&lt; enum&gt;&gt;“没有超载匹配此调用",但我不明白为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆