Could it be that my function is not returning the correct type?

I've encountered an issue with my function while filtering a labelled enumeration. It seems that the function isn't returning the expected type, and I'm not sure why.

function fromNameLabels<T extends string>(src: Array<[T, string]>): 
Array<LabelledEnum<T>> {
    return src.map(([name, label]) => ({ name, label }))
}  

function fromLabelledEnum<T extends string>(src: 
Array<LabelledEnum<T>>): { [K in T]: K } {
    return src.reduce((res, {name, label}) => {
        res[name] = name
        return res
    }, Object.create(null))
}  

type Mandant = 'REN' | 'COVEA'
type TabEnum =  Array<LabelledEnum<string>>
type MapTabEnum = Record<Mandant,TabEnum>

function getTabEnumByMandant ( mandant: Mandant) {
    return TypeRendezVousValuesMap[mandant]
}

export const TypeRendezVousValuesREN = fromNameLabels([
    ["Site","Sur site"],
    ["Visio","En visio"],
    ["Telephonique","Par téléphone"],
    ["RdvGalant","Rendez vous galant"],
    ["RdvSport","rendez vous sportif"],
    ["MatchSquash","match de squash"],
])

export const TypeRendezVousValuesCOVEA = fromNameLabels([
    ["RdvGalant","Rendez vous galant"],
    ["RdvSport","rendez vous sportif"],
    ["MatchSquash","match de squash"],
])

export const TypeRendezVousValuesMap: MapTabEnum = {
    'REN':TypeRendezVousValuesREN,
    'COVEA':TypeRendezVousValuesCOVEA
}

export const TypeRendezVousCovea = fromLabelledEnum(getTabEnumByMandant ('COVEA'))
export type TypeRendezVous = keyof typeof TypeRendezVousCovea

I am aiming for my TypeRendezVousCovea to have this specific type:

const TypeReference: {
    ReferenceSinistre: "ReferenceSinistre";
    NumeroContrat: "NumeroContrat";
    Autre: "Autre";
}

However, currently it is of this type :

const TypeRendezVousCovea: {
    [x: string]: string;
}

If anyone has any insights or possible solutions, I would greatly appreciate it. I'm using TypeScript version 3.0.1.

Answer №1

There are a few minor issues contributing to the problem. One key issue is that the function getTabEnumByMandant requires a generic type parameter in order to accurately capture the value being passed and return the correct type from the TypeRendezVousValuesMap.

Additionally, by explicitly typing TypeRendezVousValuesMap, the specific type of the object literal is not preserved. Removing the annotation would help maintain the type. To restrict TypeRendezVousValuesMap, a generic function can be used (as demonstrated below)

type LabelledEnum<T> = { name: T, label: string }
function fromNameLabels<T extends string>(src: Array<[T, string]>): Array<LabelledEnum<T>> {
  return src.map(([name, label]) => ({ name, label }))
}

function fromLabelledEnum<T extends string>(src: Array<LabelledEnum<T>>): { [K in T]: K } {
  return src.reduce((res, { name, label }) => {
    res[name] = name
    return res
  }, Object.create(null))
}

type Mandant = 'REN' | 'COVEA'
type TabEnum = Array<LabelledEnum<string>>
type MapTabEnum = Record<Mandant, TabEnum>

function getTabEnumByMandant<K extends Mandant>(mandant: K) {
  return TypeRendezVousValuesMap[mandant]
}

export const TypeRendezVousValuesREN = fromNameLabels([
  ["Site", "Sur site"],
  ["Visio", "En visio"],
  ["Telephonique", "Par téléphone"],
  ["RdvGalant", "Rendez vous galant"],
  ["RdvSport", "rendez vous sportif"],
  ["MatchSquash", "match de squash"],
])

export const TypeRendezVousValuesCOVEA = fromNameLabels([
  ["RdvGalant", "Rendez vous galant"],
  ["RdvSport", "rendez vous sportif"],
  ["MatchSquash", "match de squash"],
])

export const TypeRendezVousValuesMap = (<T extends MapTabEnum>(o: T) => o)({
  'REN': TypeRendezVousValuesREN,
  'COVEA': TypeRendezVousValuesCOVEA
})

export const TypeRendezVousCovea = fromLabelledEnum(getTabEnumByMandant('COVEA'))
// const TypeRendezVousCovea: {
//   RdvGalant: "RdvGalant";
//   RdvSport: "RdvSport";
//   MatchSquash: "MatchSquash";
// }

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

Precisely outline the function type that operates on an object, makes changes to its values, and then outputs the object in TypeScript

Can anyone help me create a function that generates a new object with the same keys as the input object, but with all values set to null? Here's the existing code: function nullify(arg) { var returnObj = {} for (var key in arg) { returnObj[ ...

Unable to pass response from httpclient post method to another custom function in Angular 4

I've implemented the addUser(newUser) function in my sign-in.service.ts file like this: addUser(newUser) { const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; let body = JS ...

What is the best way to access the original observed node using MutationObserver when the subtree option is set to

Is there a way to access the original target node when using MutationObserver with options set to childList: true and subtree: true? According to the documentation on MDN, the target node changes to the mutated node during callbacks, but I want to always ...

What is the process for importing types from the `material-ui` library?

I am currently developing a react application using material-ui with typescript. I'm on the lookout for all the type definitions for the material component. Despite attempting to install @types/material-ui, I haven't had much success. Take a look ...

Instructions on how to reset or restore to the initial spawn point

I am currently attempting to simulate a spawn process using the mock-spawn module. However, I am encountering issues with restoring the mock after running subsequent tests. I attempted to use mySpawn.resotre(), but it appears that this function does not e ...

Troubleshooting Angular 14 Custom Form Control Display Issue

I'm facing an issue while attempting to develop a custom form control in Angular 14. Despite no errors showing up in the console, my custom control is not rendering as expected. When inspecting the Elements tab in the console, I can see the parent com ...

Angular firing a function in the then clause before the initial function is executed

I have a situation where I need to make multiple service calls simultaneously, but there is one call that must be completed before the others are triggered. I have set it up so that the other calls should only happen after the .then(function() {}) block of ...

Dependencies of generic types among function arguments

Exploring the implementation of binding in a game engine, I aim to incorporate a touch of typing. /** Engine external functions */ export type Message<TBody> = { } // This function returns the same unique object for the same `s` // An internal engi ...

Ways to dynamically manipulate HTML elements in Angular 5

Recently, I've been attempting to programmatically transform an HTML element. Strangely, when I update the transform value in the console tab, it changes successfully, but for some reason it doesn't reflect in the element tab of the browser. onD ...

Exploring the Power of Vercel Deployment: Crafting a Custom CORS Middleware for Your API

Recently, I have been testing different methods to avoid a CORS error in my upcoming app deployed on Vercel. The only solution that worked for me was manually setting the headers for each API request, as shown below: export default async function handler( ...

Guide to organizing documents using an interface structure

I currently have an interface that outlines the structure of my documents within a specific collection: interface IGameDoc { playerTurn: string; gameState: { rowOne: [string, string, string] rowTwo: [string, string, string] ...

Angular - Sharing data between components with response value

I am currently in the process of restructuring my project, focusing on establishing communication between unrelated components while also waiting for a return value from a function call. Imagine having component1 with function1() and component2 with funct ...

Uh-oh! There seems to be an issue with the response. It appears that the

Struggling to navigate the graphql in apollo client/server for a Next.js project. The terminal is showing an error message No HTTP methods exported in '..\app\api\graphql\route.ts'. Export a named export for each HTTP method.. ...

Shift the Kid Element to an Alternate Holder

Currently, I am working on a project in Angular version 10. Within this app, there is a component that can be shared and will utilize the provided content through ng-content. Typically, this content will consist of a list of items such as divs or buttons. ...

Transferring information between Puppeteer and a Vue JS Component

When my app's data flow starts with a backend API request that triggers a Vue component using puppeteer, is there a way to transfer that data from Backend (express) to the vue component without requiring the Vue component to make an additional backend ...

Unable to implement new ecmascript decorators within typescript version 2.4.2

Check out this example code: function enumerable(value: boolean) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { descriptor.enumerable = value; }; } class A { @enumerable(false) a: number = 1 b: number ...

Guide on filtering FlatList Data in react native by selecting multiple categories from an array

User Interface Image I am looking to implement a filter functionality in the FlatList data based on top categories, where the filter button allows for multiple selections. The FlatList data is stored in the HotelData array, and the categories are also re ...

Creating a function within a module that takes in a relative file path in NodeJs

Currently, I am working on creating a function similar to NodeJS require. With this function, you can call require("./your-file") and the file ./your-file will be understood as a sibling of the calling module, eliminating the need to specify the full path. ...

Capturing Input Data Dynamically with Angular Forms

Is there a way to retrieve values from an unknown number of input fields in Angular? This is the code I am using to generate the input fields: <form (ngSubmit)="submit()" #custom="ngModel"> <div *ngIf="let elem of arr"> <input ...

Encountering a snag while setting up Google authentication on my website

Currently, I am in the process of integrating Google Authentication into my website. However, I have run into an error related to session management that reads as follows: TypeError: req.session.regenerate is not a function at SessionManager.logIn (C:&bso ...