Generating TypeScript Type Definitions for dynamic usage

In my client server application, I use REST calls for communication.

To avoid using the wrong types by mistake, I have defined all RestCalls in a common file (excerpt):

type def<TConnection extends Connections> =
        // Authentication
        TConnection extends '/auth/password/check/:login->get' ? Set<void, { found: boolean }, void, false>
        : TConnection extends '/auth/password/register->post' ? Set<RegisterAccount<Login>, void, void, false>
        : TConnection extends '/auth/password/login->post' ? Set<Login, void, void, false>
        ...
    

The url and method are encoded in the string, including express url parameters (/ :).

Set determines the data in the body and if authentication checks should be performed.

  1. request
  2. response
  3. response on error
  4. if authentication is needed
type Set<Input extends (Object | void), result extends (Object | void), Error extends string | object | void, NeedsAuthentication extends boolean = true> = {
        input: Input, result: result,
        error: DefaultError<Error>,
        authenticated: NeedsAuthentication
    };
    

I can then utilize the following types to access the correct values:

...

I would now like to dynamically determine at runtime whether authentication is required for a specific call. Is there a way to achieve this without workarounds?


I want to implement the following function:


    function needsAuthentication<T extends Connections>(test: T): NeedsAuthentication<T> {
        // todo find out if authentication is actually required for this url 
    }
    

This function is not part of the transmitted data but is encoded in the type mapping. The compiler will accurately map it to true or false for const strings at compile time.

Answer №1

No, the Typescript types will be generated during compilation.

You have several options:

  1. Utilize JSON-Schema (Ajv) to validate the input of incoming http json requests: https://github.com/ajv-validator/ajv
  2. Consider using Swagger, which is similar to option 1.
  3. Explore a validator that is compatible with your specific framework.
  4. There is a project that aims to create runtime asserts from Typescript types: https://github.com/skunkteam/types, although I have not personally used it.
  5. Another option is to look into https://github.com/nanoporetech/ts-runtime-typecheck, which functions similarly to option 4 but I have not tested it myself.

Answer №2

I developed a script that runs before the build process and utilizes the TypeScript compiler's typechecker to deduce the return type of the function for all potential inputs. This information is then saved to a file which is later utilized by the function.

script

    const project = new Project({});

    // adding source files
    project.addSourceFilesAtPaths("src/**/*.ts");


    function Test(path: string) {
        const dataFile = project.createSourceFile(`src/${randomUUID()}.ts`, `import * as x from "./data" ; const check = x.needsAuthentication("${path}")`);
        const declaration = dataFile.getVariableDeclarationOrThrow('check');
        const result = project.getTypeChecker().getTypeText(declaration.getType());
        return result.toLowerCase() == 'true';
    }
    const pathChecks = paths.map(x => [x, Test(x)]).reduce((p: any, v: any) => {
        p[v[0]] = v[1];
        return p;
    }, {});

    let authenticationText = `export const lookup = ${JSON.stringify(pathChecks)} as const;`
    await fs.writeFile('src/data-authentication.g.ts', authenticationText);

Within my code, I utilize

import { lookup } from './data-authentication.g';
//...
export function needsAuthentication<T extends Connections>(test: T): NeedsAuthentication<T> {
    return lookup[test];
}

Although not the most efficient method, it gets the job done...

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

Creating a Vue 3 Typescript project may lead to encountering the error message "this is undefined"

Just diving into Vue using Vite and TypeScript for my project, but running into errors during the build process. Most of them are Object is possibly 'undefined', particularly in parts of my template like this: <input :value="this.$store.s ...

An issue has occurred: [ERR_REQUIRE_ESM] You must utilize the import statement in order to load an

These are the snippets of code I'm working with: index.ts import { MikroORM } from "@mikro-orm/core" import { __prod__ } from "./constants"; import { Post } from "./entities/Post"; import microConfig from "./mikro-o ...

Executing asynchronous function in Angular using Typescript

My team and I are new to Angular and we are facing a challenge with invoking methods in sequence and returning a value. The issue is that the return statement is being executed before the completion of the execution process. We have tried various approac ...

Creating multiple-to-multiple relationships in Express: A beginner's guide

In developing a small API with Express and TypeScript, I am faced with handling both POST and GET requests. The POST request involves receiving a list of organizations, which may have daughter organizations that can also have their own daughters, creating ...

Error: Cannot access property 'tb' of an undefined value

While running the Application, I encountered an error in the declaration of constants.ts file where I was assigning data from a json file to constant variables. In the json file named object.json, I had some data structured like this: { "furniture": { ...

Is it possible for a factory provider to include optional dependencies?

As an illustration: @NgModule ({ providers: [ { provide: MyService, useFactory: (optionalDependency) => new MyService(optionalDependency) deps: [ANOTHER_DEP] } }) class MyModule {} Is it possible for useFactory to include optio ...

The error message is: "Cannot access property 'up' of an undefined object within the material UI library using theme.breakpoints."

I am encountering difficulties with the export of makeStyles. Below you can find my code and configuration: import SearchField from "../SearchField"; import { TextField, Select, useMediaQuery, Grid, Button, Box, Fade } from '@material-ui/core&ap ...

Learn how to retrieve images from the web API at 'https://jsonplaceholder.typicode.com/photos' and showcase them on a webpage using Angular10

Using the API "https://jsonplaceholder.typicode.com/photos", I have access to 5 properties: albumId: 1 id: 1 thumbnailUrl: "https://via.placeholder.com/150/92c952" title: "accusamus beatae ad facilis cum similique qui sunt" url: "https://via.placeh ...

Is Typescript capable of converting ES6 code to ES5 during transpilation?

Currently, I'm in the process of developing an application utilizing Angular 2 and TypeScript. My goal is to incorporate a JavaScript method, specifically 'filter' for arrays, that is compatible with IE 11+, Chrome 45+, and other similar bro ...

A step-by-step guide to integrating a legend on a leaflet map using Angular and the ngx-leaflet plugin

I am attempting to integrate a legend into a map generated using Asymmetrik/ngx-leaflet. The tutorial I followed for creating the map can be found at https://github.com/Asymmetrik/ngx-leaflet. There are two distinct layers on the map, each requiring its ow ...

Issue with Jest: receiving error message "Module cannot be found" despite having the package installed

Recently, I went through a cleanup and update process for a private package to make it compatible with Vite. Initially, the package.json file had the following structure: { "name": "@myRegistry/my-package", "version": &qu ...

Exploring the DynamoDB List Data Type

Currently, I am working on an angular 8 application where I have chosen to store JSON data in a list data type within DynamoDB. Inserting records and querying the table for data has been smooth sailing so far. However, I have run into some challenges when ...

Struggling to iterate through JSON data in Office Scripts?

My task involves parsing JSON data in Office Scripts to extract the headings and row details on a spreadsheet. While I have successfully fetched the data, I am encountering an error message stating that my information is not iterable at the "for" loop. ...

flushMicrotasks does not function properly in conjunction with the image.onload event

Working on an Angular project, I'm currently developing an object with an image field. The method responsible for loading the image returns a promise that resolves in the onload function of the image. When trying to test this method using the flushMi ...

Issue with Click event not working on dynamically added button in Angular 8

My goal is to dynamically add and remove product images when a user clicks the add or delete button on the screen. However, I am encountering an issue where the function is not being called when dynamically injecting HTML and binding the click event. Below ...

Error encountered in Intellij for Typescript interface: SyntaxError - Unexpected identifier

I am currently testing a basic interface with the following code: interface TestInterface { id: number; text: string; } const testInterfaceImplementation: TestInterface = { id: 1, text: 'sample text' }; console.log(testInterface ...

Enhance the performance of your React/NextJS app by controlling the rendering of a component and focusing on updating

I'm facing an issue with my NextJS application that showcases a list of audio tracks using an <AudioTrackEntry> component. This component receives props like the Track Title and a Link to the audio file from an external data source. Within the ...

I encountered a MISSING_MESSAGE error while using the next-intl npm package in my next.js application

import { useEffect } from "react"; import type { AppProps } from "next/app"; import Script from "next/script"; import { SWRConfig } from "swr"; import { useRouter } from "next/router" import { AppContext } ...

I encountered an issue where I did not receive a response when utilizing res.write() within the fetch function

Currently, I am utilizing the <res.write()> method in nodejs at https://nodejs.org/api/http.html#responsewritechunk-encoding-callback. In addition to this, I am also implementing the fetch function which can be found at https://developer.mozilla.org/ ...

Typescript library available as a private npm dependency

I have developed a Typescript library that I bundle as an npm module. During the development of my frontend application, I easily integrated this library using yarn link. As I set up GitLab CI for other developers to work on the frontend application, I am ...