Limitations of typescript generics

Sorry for the unclear title, I'm struggling to phrase this question concisely!

I'm attempting to create a class:

class Stream<Template<T,K,I>>

I realize this is not the correct syntax. So far, I have...

class Stream<T extends object, K, I extends string> {
  constructor(ledger: Ledger, template: Template<T, K, I>) {
    this.ledger = ledger;
    this.stream = ledger.streamQuery(template);
  }

  private ledger: Ledger;
  private stream: DamlStream<T, K, I, readonly CreateEvent<T, K, I>[]>;
...

My goal is to create a generic Stream where a stream can be defined as:

stream: Stream<Record>

where Record is a Template<T,K,I>.

I don't want the class definition to include Stream<T,K,I> because the T, K, and I of the Record are messy, autogenerated hash strings. It wouldn't look good.

Summary: I want to define a stream as stream: Stream<Record>, not

stream: Stream<RecordT, RecordK, RecordI>

If you have any helpful suggestions, please let me know!

Cheers

EDIT: (Further clarification)

I'd like to instantiate the Stream class with the constructor like this:

stream = new Stream(ledger, StorageRecord)
. Here, StorageRecord is a type generated from the backend and is of type Template<T,K,I> where K, T, and I sometimes have very lengthy, unattractive names.

The issue arises when trying to define a Stream class member as stream: Stream<...>.

I simply want to use Stream<StorageRecord>, for example.

I can't define Stream as class Stream<T> because ledger.streamQuery necessitates a Template argument.

I can't define Stream as

class Stream<T extends Template>
because Template itself is generic.

I need to retain T, K, and I since they are necessary in the class too.

Answer №1

To solve this issue, you can utilize the conditional syntax infer. The first generic should extend Template in a broad manner, allowing for additional generics to infer data from it and be used later in the class.

class Stream<Templ extends Template<any,any,any>, 
             T extends object=(Templ extends Template<infer A,any,any> ? A : never), 
             K extends  any  =(Templ extends Template<any,infer A,any> ? A : never),
             I extends string=(Templ extends Template<any,any,infer A> ? A : never)
             > {
    constructor(ledger: Ledger, template: Templ) {
        this.ledger = ledger;
        this.stream = ledger.streamQuery(template);
    }

    private ledger: Ledger;
    private stream: DamlStream<T, K, I, readonly CreateEvent<T, K, I>[]>;
}

For example, Stream< StorageRecord> should correctly infer the inner arguments. However, using

Stream<StorageRecord, {}, 0, "hi">
could potentially cause issues. To ensure more robust code, consider implementing the following approach:

type _inferT<Templ extends Template<any,any,any>> = Templ extends Template<infer A,any,any> ? A : never
type _inferK<Templ extends Template<any,any,any>> =(Templ extends Template<any,infer A,any> ? A : never)
type _inferI<Templ extends Template<any,any,any>> = (Templ extends Template<any,any,infer A> ? A : never)
class Stream<Templ extends Template<any,any,any>> {
    constructor(ledger: Ledger, template: Templ) {
        this.ledger = ledger;
        this.stream = ledger.streamQuery(template);
    }

    private ledger: Ledger;
    private stream: DamlStream<_inferT<Templ>, _inferK<Templ>, _inferI<Templ>, readonly CreateEvent<_inferT<Templ>, _inferK<Templ>, _inferI<Templ>>[]>;
}

However, this method can become tedious quickly, hence why incorporating shorthand references in the class generics is recommended for faster type referencing.

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

In Power BI Embedded on Google Chrome, the table's scroll bars are mysteriously missing

When viewing the embedded report, I noticed that scroll bars for the Table visual are not visible in Google Chrome but are visible in Firefox. To illustrate: Report in Power BI Workspace https://i.sstatic.net/VBmJT.png Report in Power BI Embedded http ...

What steps should I take to customize WebStorm so that it no longer automatically imports the entire Typescript paths?

Recently, I noticed a change in WebStorm after an update that affected how paths were imported in my files. Initially, when typing @Component and letting WebStorm automatically import the path, it would use the following format: import { Component } from ...

Experiencing "localhost redirect loop due to NextJS Middleware" error

After successfully integrating email/password authentication to my locally hosted NextJS app using NextAuth, I encountered an issue with the middleware I created to secure routes. Every time I tried to sign out, I received an error stating "localhost redir ...

Behavior of Shadow DOM role when using the <a> element without an href attribute

Recently, I started working with the shadow DOM and encountered a strange issue: In my Ionic Angular application, there is a text styled like a link in this form (simplified): <a href="${ifDefined(this.href)}">link</a> When testing ...

Error TS2305: The module "@prisma/client" does not have an export named "User"

Setting up a Gitlab CI for my nestjs project using prisma has been my current challenge. I keep encountering this error when running the pipeline: see image here This is what my .gitlab-ci.yml looks like: image: node:latest stages: - build build: st ...

Using Angular 2 to convert and display data as a particular object type in

I have recently developed a basic application using the Angular2 tutorial as my guide. Initially, I established a straightforward "Book" model: /** * Definition of book model */ export class Book { public data; /** * Constructor for Book ...

"Revamping Your Design: The Power of Angular 4

I am working with two different layouts in my project: <div *ngIf="!loginPanel" class="login1"> <a (click)="showLoginPanel()">Login</a> </div> <div *ngIf="loginPanel" class="login2"> <input type="text" placeholder="user ...

Creating several light beams from a rotated structure

My current challenge involves shooting multiple rays from a rotating mesh in various directions targeting points on a circle divided by the number of rays. To assist with debugging, I have added ArrowHelpers for each ray with a goal for the arrows to turn ...

Even as I create fresh references, my JavaScript array object continues to overwrite previous objects

Coming from a background in c# and c++, I am facing some confusion with a particular situation. Within the scope of my function, I am creating a new object before pushing it into an 'array'. Strangely, when I create the new object, it appears to ...

Guide on verifying API response structure in Playwright with TypeScript

As a newcomer to Playwright, my focus is on writing API tests in TypeScript with an API response structured like this: { "id" : "abc123", "appCode" : "09000007", "applicationReference" : "ABCDEF& ...

Pressing the F5 key will cause i18next to revert back to the original default

i18n.js import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import enTranslation from '../locales/en.json'; import trTranslation from '../locales/tr.json'; import deTranslation from '.. ...

Angular 2 Error: TS2322 - The type 'Subscription' cannot be assigned to the type 'Observable<MouseEvent>'

I have implemented the click-outside directive using this plunk --> http://embed.plnkr.co/v7BMUv/ But when I try to compile my TypeScript code, I encounter the following errors: Error TS2322: Type 'Subscription' is not compatible with type & ...

Creating input fields in Angular 2

Can someone guide me on how to sum the values entered in two input fields? Here is my HTML code snippet. I'm not sure if there's anything missing in the ts file. <div class="small-7 columns"> <md-input-container> <input t ...

Unexpected token error in TypeScript: Syntax mistake spotted in code

Being new to Angular, I understand that mastering TypeScript is crucial for becoming a skilled Angular developer. Therefore, I created this simple program: function loge(messag){ console.log(messag); } var message:string; message = "Hi"; loge(messa ...

Tips for universally updating the FormData TypeScript interface within React Native applications

While attempting a simple append with FormData in React Native like the following... const formData = new FormData(); formData.append('image-data', { uri: '/awesome-chat-app/ImagePicker/abb9-a435046e971c.jpg', name: 'image001. ...

Encountered a problem with AngularUniversal prerendering: UnhandledPromiseRejectionWarning: Unable to locate NgModule metadata for 'class{}'

Objective The task may seem lengthy, but it's straightforward! Currently, I am utilizing Angular Universal for Server-Side Rendering (SSR) by following a tutorial. The Universal/express-engine has been installed, main.js is generated in the dist/pro ...

Exploring the capabilities of combining Typescript with withStyles in the latest @material-ui/core framework

I have been working on updating some old Typescript code that was using material-ui@next to now use @material-ui/core. Typescript Version: 2.8.3 @material-ui/core: 1.1.0 I created a simple component that accepts a single prop, but when I try to use it, t ...

Error: The function jquery_1.default is not recognized by webpack

I am encountering an issue with using external imports of jQuery in webpack. Despite trying different import syntaxes such as import $ from 'jquery', import * as $ from 'jquery, and const $ = require('jquery'), I continue to receiv ...

Error 404 occurs when attempting to retrieve a JSON file using Angular's HTTP

I'm having an issue with my service code. Here is the code snippet: import {Injectable} from '@angular/core'; import {Http, Headers, RequestOptions} from '@angular/http'; import 'rxjs/add/operator/map'; import {Client} f ...

I am currently working to resolve this particular wildcard issue with the help of TypeScript

I've been working on solving the wildcard problem with TypeScript, but I'm running into issues with some of the test cases I've created. Here's a brief overview of how the code operates: A balanced string is one where each character ap ...