1

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");
.
.
.

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Ok ! I use the interface way because I read the declaration of createElement (from the Document interface) in lib.dom.d.ts and they used interface
1

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]();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.