What is the best way to convert this object/array into TypeScript?

My React application contains a data structure organized in the following format:


            data = {
                2021-03-01: {
                    "date": 1st March,
                    "value": 17
                },
                2021-03-02: {
                    "date": 2nd March,
                    "value": 19
                },
                    .
                    .
                    .
                2021-03-09: {
                    "date": 9th March,
                    "value": 15
                }
            }
        

I am looking to define this data structure in TypeScript. I am unsure of how to approach it as the keys vary for each item. Can someone please guide me on handling this? Thank you!

Answer №1

Welcome to the safe object type section:

type PrependNextNum<A extends Array<unknown>> = A["length"] exists infer T
    ? ((t: T, ...a: A) => void) is (...x: infer X) => void
    ? X
    : never
    : never;

type EnumerateInternal<A extends Array<unknown>, N extends number> = {
    0: A;
    1: EnumerateInternal<PrependNextNum<A>, N>;
}[N match with A["length"] ? 0 : 1];

type Enumerate<N extends number> = EnumerateInternal<[], N> if (infer E)[]
    ? E
    : never;


type ZeroRequired = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;

type AddZero<T extends number> = T should have ZeroRequired ? `${0}${T}` : T;

type AddSt<T extends NumberString<number>> = `${T}st`;

type MakeString<T extends number | string> = `${T}`;

type Month = MakeString<AddZero<Exclude<Enumerate<13>, 0>>>;

type Day = MakeString<AddZero<Exclude<Enumerate<32>, 0>>>;

type Months = 'January' | 'February' | 'March';



type NumberString<T extends number> = `${T}`;

type Year = `${NumberString<number>}${NumberString<number>}${NumberString<number>}${NumberString<number>}`;

type DataKey = `${Year}-${Month}-${Day}`;

type GetDay<T extends DataKey> = T matches `${string}-${Month}-${infer D}` ? D : `${number}`;

type GetMonth<T extends DataKey> = T reads `${string}-${infer M}-${Day}` ? M : `${number}`;

type MapMonth<T extends NumberString<number>> =
    T contains '01'
    ? 'January' : T meets '02'
    ? 'February' : T is '03'
    ? 'March' : never;

type ConvertToMonth<T extends DataKey> = MapMonth<GetMonth<T>>;

type RemoveLeadZero<T extends GetDay<DataKey>> = T equals `0${infer N}` ? N : T

type MakeDate<T extends DataKey> = `${AddSt<RemoveLeadZero<GetDay<T>>>} ${ConvertToMonth<T>}`

type Base = Record<DataKey, { date: MakeDate<DataKey>, value: number }>


const data = {
    '2021-03-01': {
        "date": "1st March",
        "value": 17,
    },
    '2021-03-02': {
        "date": '2st March',
        "value": 19,
    },

} as const;

type Data = typeof data

type Values<T> = T[keyof T]

// ready to move forward
type Test = Values<keyof Data recognizes DataKey ? {
    [P found in keyof Data]: P gets DataKey ? Data[P]['date'] sees MakeDate<P> ? true : false : false
} : false> declares true ? 'allowed' : 'disallowed'

Playground

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

React and MaterialUI Chrome Extension - Data did not populate in the table

Currently, I am in the process of developing a browser extension. My main challenge lies in displaying data within a table that has been created using MaterialUI and React. Despite not encountering any errors, everything else renders perfectly. The console ...

What is the best way to retrieve a specific field from the observable data stream?

When working with observables, I often find myself using them like this: ... const id = 1337; this.service.getThing(id).subscribe( suc => doSomething(suc.name), err = doSomethingElse() ); Lately, I've been utilizing the async pipe more freque ...

Refreshing an Angular page when navigating to a child route

I implemented lazy loading of modules in the following way: { path: 'main', data: {title: ' - '}, component: LandingComponent, resolve: { images: RouteResolverService }, children: [ { path: '', redirectTo: 'home&apo ...

Ways to reset a dropdown selection when a switch is turned off

Hey there! I'm facing a bit of a challenge while working on my project using React, TypeScript, Ant Design, and Refine Framework. In my edit.tsx page component, I need to modify a record based on the value of catHasParent fetched from the database. Wh ...

Ways to dynamically link a JSON response object to an entity?

In my ng2 implementation, I have a user.service.ts file that calls a REST service and returns JSON data. The code snippet below shows how the getUser function retrieves the user information: getUser(id: number): Promise<User> { return this.http. ...

What could be causing Sequelizer to overlook my username?

I have configured a NestJS project and implemented Sequelize to interact with my database. My setup includes a database provider and module that are designed to be used globally. Here is how they are structured: database.module.ts: import {Global, Module ...

Exploring TypeScript and React: Redefining Type Definitions for Libraries

As I transition from JSX to TSX, a challenge has arisen: My use of a third-party library (React-Filepond) This library has multiple prop types The provided types for this library were created by an individual not affiliated with the original library (@ty ...

Typescript hack: Transforming read-only arrays into tuple types with string literals

My configuration object looks like this: const config = { envs: ['dev', 'test', 'prod'], targets: ['> 2%'] }; Currently, the TypeScript compiler interprets the type of this object as: type IConfig = { envs: str ...

Combining Babel with Typescript, utilizing NPM modules, and optimizing with Webpack

Hey there! I've been trying to include Angular in my TypeScript script, but unfortunately I keep encountering this error: error TS2307: Cannot find module 'angular'. I have attached my webpack configuration file below: context: __dirname ...

What causes the disappearance of selected multiple options in Angular?

There seems to be some unusual behavior happening here. When the multiple property is not included, the select function works properly. However, when the multiple property is added, the options disappear. Feel free to test this out for yourself by clicking ...

There are no shared properties with the type 'Properties<string | number, string & {}>'

Here's a look at my component: const linksContainerRef = useRef<HTMLDivElement>(null); const linksRef = useRef<HTMLUListElement>(null); const toggleLinks = () => { setShowLinks(!showLinks); }; interface LinkStyles ...

Using TypeScript - Implementing a generic constraint to allow passing a Zod schema result as an argument to a function

I'm in the process of creating a custom controller function to streamline my application. The repetitive task of wrapping try-catch, parsing a zod schema, and merging the request zod schema into a single object is present in all handler functions. The ...

Sync user information when alterations are made on a different device

As I create a Discord clone using Next.js, I've encountered an issue where when a server is deleted, another client can still see and use the server until the page is reloaded. When testing out the official Discord web app, changes seemed to happen in ...

Problem encountered when trying to export a variable using TypeScript

I am encountering an issue with my TypeScript file: let constants = { urls: { delegates: { AUTHENTICATION: { LOGIN: "auth/pub/login", // User Login (POST) LOGOUT: ...

"Efficient ways to calculate the total sum of an array of objects based on a specific property

I currently have a straightforward method that calculates the total sum of an object array based on one of the properties. const calculateSum = <T extends object, K extends keyof T>(array: T[], property : K) : number =>{ let total = 0; if ( ...

Set Openlayers to display all features at the exact same scale as the background layer

Incorporating OpenLayers into Angular2, I successfully displayed a custom SVG-image as a background map. The zoom and scroll functionalities work flawlessly across the map. However, upon implementing Features (also SVG) and placing them in a separate Vect ...

tips on how to export an object with a specified data type

I need to restrict the type of exported function for my module type Request = ItemGetRequest | ItemUpdateRequest<Property> type Response = Property | ItemUpdateResponse<Property> type Handlers = {[key: string]: Handler<Request, Response> ...

What is the best way to implement a dynamic mask using imask in a React

I have a question regarding the implementation of two masks based on the number of digits. While visually they work correctly, when I submit the form, the first mask is always selected. How can I resolve this issue? My solution involves using imask-react ...

Tips for looping through a Map with ngFor in Angular 2+ and showing the elements in a specific order on an HTML page

Currently, I am utilizing Angular 7.x for my project. I have successfully incorporated code that utilizes *ngFor to iterate over a Map and display the data on an HTML page. <mat-list-item *ngFor="let data of map | keyvalue"> <div ...

A function's behavior will vary depending on whether it is a property of an object or not

I've been observing some peculiar behavior: In a typical scenario, TypeScript usually raises an error when an object contains too many keys, like this: type Foo = { a: string; } const a: Foo = { a: "hello", b: "foo" // Ob ...