Home > Blockchain >  Typescript polymorphism with class
Typescript polymorphism with class

Time:07-11

I try to create a function to create a piece of chess almost like the document.createElement:

class pawn extends piece {

}

class bishop extends piece {

}

class rook extends piece {

}

class king extends piece {

}

class queen extends piece {

}

class knigth extends piece {

}

export interface pieces {
    "pawn": pawn
    "bishop": bishop
    "rook": rook
    "king": king
    "queen": queen
    "knigth": knigth
}

export function createPiece<K extends keyof pieces>(pieceName: K, options?: pieceInit): pieces[K]{
    /// ???
}

But I don't know what I need to return in my createPiece function... I try

export function createPiece<K extends keyof pieces>(pieceName: K, options?: pieceInit): pieces[K]{
     return pieces[pieceName]
}

But I got the following error : 'pieces' only refers to a type, but is being used as a value here

My goal is :

const piece1:pawn = createPiece("pawn");
const piece2:queen = createPiece("queen");
.
.
.

CodePudding user response:

You can if you define the interface as a const. Fully typed it would look like so:

type PiecesKey = keyof Pieces;
type Piece<T extends PiecesKey> = Pieces[T];

type Pieces = {
    pawn: pawn;
    bishop: bishop;
    rook: rook;
    king: king;
    queen: queen;
    knigth: knigth;
};

const pieces = {
    pawn: pawn,
    bishop: bishop,
    rook: rook,
    king: king,
    queen: queen,
    knigth: knigth,
};

type pieceInit = {};

export function createPiece<K extends PiecesKey>(
    pieceName: K,
    options?: pieceInit,
): Piece<K> {
    return new pieces[pieceName]();
}

CodePudding user response:

You defined pieces as an interface. You can only access information about interfaces during compile-time and not during runtime. That's why the line return pieces[pieceName] fails to compile.

You should instead define pieces as an object.

export const pieces = {
    "pawn": pawn,
    "bishop": bishop,
    "rook": rook,
    "king": king,
    "queen": queen,
    "knigth": knigth
}

We can use this object to look up the keys during runtime and we can also extract the type information of pieces for use during compile-time.

export function createPiece<
  K extends keyof typeof pieces
>(pieceName: K): typeof pieces[K] {
  return pieces[pieceName]
}

So instead of using pieces directly in the generic type, you can use typeof pieces to get the type of the pieces object.

Playground

CodePudding user response:

IN you function, you are returning return pieces pieces is a type. You cannot use a type like you would use a value. What are you trying to do more specifically? I will give you a hand :)

  • Related