Creating a TypeScript generic record with specified keys

I need to validate in TypeScript whether an object contains the specified keys (from SingleShopColumns or MultishopColumns) and has a validations property that is an array of strings.

I am using Record and generics, but any simple method of representing this structure in a generic way would suffice.

export type SingleShopColumns =
  | 'SKU'
  | 'Priority';

export type MultishopColumns =
  | 'Redundant Date'
  | 'Priority';

export type ValidatorSchema<T> = Record<keyof T, { validations: string[] }>;

export const SINGLE_SHOP_SCHEMA: ValidatorSchema<SingleShopColumns> = {
    'SKU': {
        validations: ['validateString']
    },
    'Priority':  {
        validations: ['validateString']
    },
    'Does_not_exist_should be error': {
        validations: ['validateString']
    }
};

export const MULTISHOP_SCHEMA: ValidatorSchema<MultishopColumns> = {
    'Redundant Date': {
        validations: ['validateString']
    },
    'Priority':  {
        validations: ['validateString']
    }
};

TypeScript playground with this code

Encountering an issue

Type '{ SKU: { validations: string[]; }; Priority: { validations: string[]; }; 'Does_not_exist_should be error': { validations: string[]; }; }' is not assignable to type 'ValidatorSchema<SingleShopColumns>'. Object literal may only specify known properties, and ''SKU'' does not exist in type 'ValidatorSchema<SingleShopColumns>'.

Answer №1

T is currently being used as a key. Please eliminate the keyof and introduce a constraint:

export type ValidatorSchema<T extends string> = Record<T, { validations: string[] }>;

Answer №2

Your existing T is already a comprehensive collection of keys, so simply:

export type ValidatorSchema<T extends string|number|symbol> = 
    Record<T, { validations: string[] }>;

Instead of creating a new union, as shown below:

export type ValidatorSchema<T> = 
    Record<keyof T, { validations: string[] }>;

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

Having difficulty utilizing defineProps in TypeScript

For some time now, I've been utilizing withDefaults and defineProps. Unfortunately, this setup has recently started failing, leaving me puzzled as to why! Here's a simple SFC example: <script setup lang = "ts"> const props ...

What is the recommended approach in Angular for unassigned @Input() variables when using TypeScript strict mode?

Issue at Hand After upgrading my Angular version from 10 to 13, I encountered a problem with the new TypeScript strict compiler mode. The upgrade required me to assign values to all declared variables upon initialization, causing issues with properties de ...

Optimal method for retrieving data from a JSON object using the object's ID with a map

Can you teach me how to locate a json object in JavaScript? Here is a sample Json: { "Employees" : [ { "userId":"rirani", "jobTitleName":"Developer", "preferredFullName":"Romin Irani", "employeeCode":"E1", "region":"CA", "phoneNumber":"408-1234567", " ...

Dissimilarities in behavior between Angular 2 AOT errors

While working on my angular 2 project with angular-cli, I am facing an issue. Locally, when I build it for production using ng build --prod --aot, there are no problems. However, when the project is built on the server, I encounter the following errors: . ...

Encountered error message: "Cannot assign argument of type '() => () => boolean' to parameter of type 'EffectCallback'"

I recently started working with TypeScript. I encountered an issue when attempting to utilize useEffect in TypeScript within a React context, Error: Argument of type '() => () => boolean' is not assignable to parameter of type 'Effec ...

TypeScript - Converting into individual compiled files

Currently, I am working on a project that consists of lengthy source files. While this is advantageous for imports, it poses challenges in terms of maintenance. For instance: /main/core.ts export type Foo { ... } export interface Bar { ... } export cla ...

Accessing Properties or Methods in Angular2 Components

My application consists of 3 main components: PageMenu, LoginSession, and LoginForm. The purpose is to establish a connection between the variables in LoginSession and PageMenu, allowing for the proper functionality of the LoginForm component. PageMenu: ...

Display embedded ng-template in Angular 6

I've got a template set up like this <ng-template #parent> <ng-template #child1> child 1 </ng-template> <ng-template #child2> child 2 </ng-template> </ng-template> Anyone know how t ...

The 'Key' identifier is not valid for indexing the 'Object' data type

Currently attempting to incorporate functional pluck with a specific sound type, but encountering an issue: function extract<Object extends {}, Key = keyof Object>(key: Key): (o: Object) => Object[Key] { return object => object[key]; } Erro ...

Where is the best location to store types/interfaces so that they can be accessed globally throughout the codebase?

I often find myself wondering about the best place to store types and interfaces related to a specific class in TypeScript. There are numerous of them used throughout the code base, and I would rather not constantly import them but have them available gl ...

The function cannot accept a string as an argument, it specifically requires a Blob

Having run into a dilemma here. import React, { useState } from "react"; const PhotoUploader: React.FC = () => { const [photo, setPhoto] = useState(""); let reader = new FileReader(); reader.readAsDataURL(photo); const hand ...

The function of type 'PromiseConstructor' is not executable. Should 'new' be added? React TypeScript

.then causing issues in TypeScript. interface Props { type: string; user: object; setUserAuth: Promise<any>; } const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if (type === "signup" ...

Improve your code by avoiding the use of multiple ngIf statements

Looking for ways to shorten my code for better readability. I have multiple ngIf statements with various conditions for numbering lists (e.g., 1, 1.1, 1.1.1) Here is a snippet of the code from my template: <span *ngIf="...">{{...}}.</span> .. ...

Encountering problem with React Typescript fetching data from Spring Data REST API: the error message "Property '_embedded' does not exist" is being displayed

I am currently working on a React application that utilizes Typescript to fetch data from a Spring Data REST API (JPA repositories). When I make a specific request like "GET http://localhost:8080/notifications/1" with an ID, my JSON response does not pose ...

ESLint and Prettier are butting heads when trying to run their commands consecutively

My package.json file includes two commands: "format": "prettier --write \"{src,{tests,mocks}}/**/*.{js,ts,vue}\"", "lint": "eslint . -c .eslintrc.js --rulesdir eslint-internal-rules/ --ext .ts,.js,.vue ...

I can't seem to understand why I am receiving an undefined property when trying to access an

While working with typescript and react within a project created using create-react-app, I encountered an issue during runtime: Cannot read property 'Customer' of undefined. This error occurred while utilizing the following module imports: impor ...

Guide on utilizing a declaration within a third-party module

I have encountered an issue while using the fingerprintjs2 library, as the declaration provided in DefinitelyTyped seems incomplete and incompatible. In order to resolve this, I decided to create my own declaration within my project. However, I am facing ...

Mastering GraphQL querying in React using TypeScript

After successfully setting up a graphql and being able to use it in Postmen, here is how it looks: query listByName($name: String!) { listByName(name: $name) { id name sortOrder } } My variable is defined as {"name&quo ...

Error: The class you are attempting to access is

Currently, I am utilizing Vite.js along with TypeScript. My TypeScript file is located in 'src/vmodel/VGraph'. Within the index.html file, I import the aforementioned file as follows: <script type="module" src="/src/vmodel/VGrap ...

Issue encountered while creating Next.js 13.4 application: The type 'ResolvingMetadata | undefined' does not meet the requirement of 'ResolvingMetadata'

I'm currently working on dynamically generating metadata for my Next.js 13.4 application using this code snippet: export async function generateMetadata( { params, searchParams }: Props, ) { try { // extract the route parameters ...