Generic type mapping of TypeScript interface properties

I am struggling to get this to function correctly

interface ObjectPool<Ids, T> {
  pool: {
    [K in Ids]: T<K>;
  };
};

interface Player<Id> {
  id: Id;
}

let playerPool: ObjectPool<0 | 1 | 2, Player>;

in a way that

playerPool[0].id === 0;
playerPool[1].id === 1;
playerPool[2].id === 2;
// playerPool[3] error

however TypeScript is indicating that I require a generic parameter at Player in

let playerPool: ObjectPool<0 | 1 | 2, Player>;
so I attempted
let playerPool: ObjectPool<0 | 1 | 2, Player<_>>;
but it did not resolve the issue either

Answer №1

When using T<K>, the type T must be a specific type operation (e.g., type T<K> = ... or interface T<K> { ... or class T<K> ...). It is not possible to have T<K> where T is a generic type parameter. To achieve this, higher-kinded types would be required, as mentioned in microsoft/TypeScript#1213, which TypeScript does not support directly.

If you rethink your approach and find a way to represent what you need without using higher-kinded types, it's better. For example:

type ObjectPool<P extends PropertyKey, T> =
  { [K in P]: { id: K } & T };

You can then define types like Player and use them accordingly:

interface Player {
  id: number,
  name: string,
}

This allows an

ObjectPool<0 | 1 | 2, Player>
to behave as expected:

function processPlayerPool(playerPool: ObjectPool<0 | 1 | 2, Player>) {
  playerPool[0].id === 0;
  playerPool[1].id === 1;
  playerPool[2].id === 2;
  playerPool[2].name;
  playerPool[3] // error
}

Keep in mind that trying to index over numeric literals may cause issues with analysis by the compiler. Consider this when working with wallPool.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the reason behind tsc disregarding the include and exclude options in tsconfig.json?

I am facing an issue with my tsconfig.json file: { "compilerOptions": { "target": "ES6", "lib": [ "DOM", "ES6" ] }, "include": [ "src/server/**/*&q ...

send mouse event to component when clicked

Looking to retrieve mouse coordinates in an Angular component. This is the HTML snippet: <div id="container" class="fullSize" style="height:100%;" (click)="onClick(ev)"></div> And here's the corresponding function in the TypeScript file ...

Having trouble pushing to an array in Angular typescript? It seems to be returning as undefined

As a newcomer to Angular with a basic understanding of JavaScript, I am attempting to create a program that can solve Sudoku puzzles. In a 9x9 grid, there are a total of 81 points or squares. To efficiently check for violations of Sudoku rules - no repeati ...

What steps should I take to troubleshoot the ParseError related to the restriction of using 'import' and 'export' exclusively with 'sourceType: module' for importing UpgradeAdapter?

I have been working on upgrading an angular.js app to angular 2, following the guidelines provided at https://angular.io/docs/ts/latest/guide/upgrade.html. The application is already coded in Typescript, and we are using browserify and tsify for compiling ...

Angular interceptor automatically aborting API request

I have implemented a guard in my Angular application to validate user authorizations before granting access to a specific page. The guard makes an asynchronous API call to retrieve the necessary authorization information. While most of the time it works sm ...

The minimum and maximum validation functions are triggered when I am not utilizing array controls, but they do not seem to work when I use array controls

Take a look at the stack blitz example where min and max validation is triggered: https://stackblitz.com/edit/angular-mat-form-field-icrmfw However, in the following stack blitz with an array of the same controls, the validation does not seem to be worki ...

The JSON object cannot be assigned to the IntrinsicAttributes and customType data types

Currently, I'm facing a challenge with reading JSON data into an array of type pinImage. My goal is to loop/map through my pinImage objects and pass each one to a child component called PinCard, which is specifically designed to accept an object of ty ...

The operator is being invoked multiple times beyond originally anticipated

I am currently working on developing code that paginates a result set using the expand operator until a specific number of resources have been fetched. Below is the code snippet I have written so far (excluding the actual async call logic): import { Obser ...

I am facing issues with my filtering functionality on the Angular Typescript mat-table component

I am facing issues while trying to filter my table, the reaction is not correct and I can't seem to find where I went wrong. Here is the HTML part : <mat-form-field appearance="outline"> <mat-label>Search</mat-label> & ...

Guide on inputting Vue component in props

<template> <v-dialog width="auto" v-model="isShown" transition="dialog-bottom-transition" > <v-card> <v-card-title v-if="title"> {{ title }}</v-card-title> ...

Creating nested return types: A guide to defining function return types within a Typescript class

My large classes contain functions that return complex objects which I am looking to refactor. class BigClass { ... getReferenceInfo(word: string): { isInReferenceList:boolean, referenceLabels:string[] } { ... } } I am considering somethi ...

Accessing data from Firebase Database Object

I am currently facing a challenge in extracting a username value from my firebase database and then displaying it in a console log statement. The issue lies in fetching the child value instead of just the object. How can I retrieve the child value and prin ...

Customizing variables in React based on the environment

I am working on a React app that includes a chart component which calls an external API. When the app is running locally, the API URL is set to localhost:8080. However, when the app is deployed, the API URL needs to be changed to prod:8080. I have tried ...

NextJS VSCode Typescript results in breakpoints becoming unbound

I have been following the instructions provided by Next.js from their official documentation on debugging using Visual Studio Code found here: https://nextjs.org/docs/advanced-features/debugging#using-the-debugger-in-visual-studio-code When attempting to ...

Utilizing Typescript generics with an optional second parameter

Learning about generics in typescript has been quite challenging for me. However, I was able to make it work successfully. export type Events = { LOGIN: undefined NAVIGATION: { screen: string } SUPPORT: { communication_method: 'chat&ap ...

Expanding the session object with express-session

Seeking assistance with TypeScript and Express session integration. I've been exploring ways to extend my session object, specifically through merging typings based on the documentation provided: In my types/session.d.ts file, I have the following i ...

Scrolling to the bottom of an ion-content in Ionic 4

I am currently developing a chat page with Ionic 4 and I'm attempting to implement an automatic scroll feature to the bottom of the page. However, the method I tried using doesn't seem to be working as expected: import { IonContent } from "@ioni ...

What is the most efficient method for examining dependencies in Yarn 2 (berry)?

Is there a way to check for vulnerabilities in Yarn 2 dependencies? In Yarn 1.x, you could run yarn audit, similar to npm audit. However, this command is not available in Yarn 2. According to this issue on the Yarn berry Github, it may not be implemented ( ...

Retrieving the return type of generic functions stored in a map

In this unique scenario, I have a dictionary with polymorphic functions that accept the same argument but return different results: const dict = { one: { foo<A>(a: A) { return [a] as const } }, two: { foo<A>(a: A) { ...

Dragula drag and drop in a single direction with Angular 2 copy functionality

Attempting to utilize ng2 dragula for one-way drag and drop with copy functionality. Below is the template I am working with: `<div> <div class='wrapper'> <div class='container' id='no-drop' [dragula]=& ...