当我指定类型时,打字稿显示“任何”

时间:2021-04-09 12:00:08

标签: typescript typescript-generics

让我们创造一个情境。有一个简单的抽象类定义棋盘游戏中的棋子,例如国际象棋或跳棋。

export abstract class Piece<Tags, Move, Position = Vector2> {
  public constructor(public position: Position, public tags = null) {}
  public abstract getMoves(board: Board<Tags, Move, Position>): Move[]
}

Board 也是一个抽象类。

export abstract class Board<Tags, Move, Position = Vector2> {
  public constructor(
    public size: Position,
    public pieces: Piece<Tags, Move, Position>[]
  ) {}
}

当我尝试扩展这个类时,Typescript 说 board 方法中的 getMovesany

class Checker extends Piece<Tags, Move> {
  getMoves(board /*← any ?*/) {
    return []
  }
}

但是为什么呢?我对泛型或抽象类有什么误解吗?

3 个答案:

答案 0 :(得分:0)

你必须声明一个与抽象类具有相同签名的方法,以证明你已经履行了抽象类的契约。

class Checker extends Piece<Tags, Move> {
  public getMoves(board: Board<Tags, Move, Position>): Move[]{
    return []
  }
}

之后,您将能够创建一个 const piece:Piece = new Checker() 并能够依赖于对piece.getMoves(board) 调用的类型。

这个例子展示了基本模式(省略了你没有提供实现的类型)...

enter image description here

答案 1 :(得分:0)

这与泛型无关。

例如当你创建一个简单的函数并且不指定参数类型时,它是 any

function test(arg) {
// arg is of type any
}

另一个问题是打字稿根本没有为被覆盖的成员提供上下文输入。所以你必须在子类中再次列出所有参数和类型。
Consider contextually typing class member functions by their base class/interface members #1373

答案 2 :(得分:0)

Typescript 支持 methods overloading。编译器无法推断参数的类型,因为您作为开发人员可以指定多个方法签名:

class Checker extends Piece<Tags, Move> {

  getMoves():Move[];
  getMoves(x: number):Move[];
  getMoves(board: Board<Tags, Move, Position>):Move[];
  getMoves(board: any):Move[] {
    return [];
  }
}

因此,您必须明确指定实现的方法签名。

相关问题