Defining assertions with specified type criteria

Looking to do something special in TypeScript with a class called Foo. I want to create a static array named bar using const assertion, where the values are restricted to the keys of Foo. This array will serve as the type for the function func while also acting as a runtime check.

Here's my current setup: (more details in TS Playground)

class Foo { a?: string; b?: string; c?: string }

const bar = ['a', 'b'] as const // this should throw an error if 'd' is added to the array

function func(arg: typeof bar[number]) { // TypeScript should recognize arg as a key of Foo
  // ...
  // utilizing bar at runtime
}

I've also attempted:

const bar: (keyof Foo)[] = ['a', 'b']
// but now arg is considered any key of Food, accepting all keys not just 'a' and 'b'

const bar: (keyof Foo)[] = ['a', 'b'] as const
// results in an Error: The type 'readonly ["a", "b"]' is 'readonly' and cannot be assigned to the mutable type '(keyof Foo)[]

Pick provides an object version that doesn't suit this scenario.

Is there a solution for this?

Answer №1

Can we try a different approach here?

class Bar { x?: string; y?: string; z?: string }

function getArguments<T extends ReadonlyArray<keyof Bar>>(args: T): T {
  return args
}

const baz1 = getArguments(['x', 'y', 'z', 'w'] as const) // error

function function1(arg: typeof baz1[number]) {
  // ...
  const b = new Bar()
  console.log('baz', baz1)
  console.log('b[arg]', b[arg])
}

const baz2 = getArguments(['x', 'y'] as const)

function function2(arg: typeof baz2[number]) {
  // ...
  const b = new Bar()
  console.log('baz', baz1)
  console.log('b[arg]', b[arg])
}

function2('z') // error

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

Tips on downloading an image using the URL in nestjs

I'm trying to retrieve a link and save the associated image in the static folder, but I seem to be encountering some issues with my code. Here's what I have so far: @Injectable() export class FilesService { createFileFromUrl(url: string) { t ...

JEST: Troubleshooting why a test case within a function is not receiving input from the constructor

When writing test cases wrapped inside a class, I encountered an issue where the URL value was not being initialized due to dependencies in the beforeAll/beforeEach block. This resulted in the failure of the test case execution as the URL value was not acc ...

What is the best way to specify data types for all attributes within an interface?

In building an interface for delivering strings in an i18n application: interface ILocaleStringsProvider { 'foo': string 'bar': string 'baz': string 'blablabla': string // numerous other string properties ...

Changing {number, Observable<string>} to Observable<number, string> is a necessary transformation to be made

Is there a way to convert an array of objects with the following structure: { id: number, data: Observable<string> } into an array of objects with this structure: Observable<{id: number, data: string}> using only RxJS operators? ...

Encountering issues in Angular 2 when attempting to pass data into root component through ng-content and binding. Objective: Creating a reusable form component

I currently have a .NET MVC application and I'm looking to integrate Angular 2 into it. The structure of my page is as follows: <html> <head>css imports and jquery imports</head> <body> <div> a bunch of table ...

Ways to retrieve a variable from a separate TypeScript document

A scenario arises where a TypeScript script contains a variable called enlightenFilters$: import { Component, Input, OnInit } from "@angular/core"; import { ConfigType, LisaConfig } from "app/enrichment/models/lisa/configuration.model"; ...

Instructions for disabling editing for a specific cell within an inline editable row in primeNG

I am currently using PrimeNG DataTable with Angular, where the rows are editable as shown in the example in the documentation: https://www.primefaces.org/primeng/#/table/edit. However, I am facing an issue where I want to exclude one cell from being editab ...

The typescript error TS2339 is triggered by the property 'webkitURL' not being found on the 'Window' type

Currently utilizing Angular 2 in a project that is compiled with TypeScript. Encountering an issue when attempting to generate a blob image: Error TS2339: Property 'webkitURL' does not exist on type 'Window' The TypeScript code causi ...

Troubleshooting: Issues with Angular2 compatibility on Safari version 9.1.2

I am encountering an issue with running my angular2 app on Safari 9.1.2. It works fine on all higher versions of Safari as well as other browsers such as Chrome, Firefox, Opera, and Edge. However, when I try to run it on Safari 9.1.2, I receive the followi ...

having difficulties sorting a react table

This is the complete component code snippet: import { ColumnDef, flexRender, SortingState, useReactTable, getCoreRowModel, } from "@tanstack/react-table"; import { useIntersectionObserver } from "@/hooks"; import { Box, Fl ...

Vite HMR causes Vue component to exceed the maximum number of recursive updates

After making changes to a nested component in Vue and saving it, I noticed that the Vite HMR kept reloading the component, resulting in a warning from Vue: Maximum recursive updates exceeded... Check out the online demo on stackblitz. Make a change in Chi ...

What is the best way to emphasize when the path matches exactly with '/'?

Is there a way to highlight the path only when it exactly matches '/'? Currently, even on 'Page 2', the 'Home' link is still highlighted. Check out the plunker here .active { color: red; } <a routerLinkActive="active" r ...

Issue with rejecting a promise within a callback function in Ionic 3

Within my Ionic 3 app, I developed a function to retrieve a user's location based on their latitude and longitude coordinates. This function also verifies if the user has location settings enabled. If not, it prompts the user to switch on their locati ...

Error message thrown by node express.js indicating that response headers cannot be reset once they have been sent

As a newcomer to both node and express, I may be making a silly mistake. If you want to see the complete source code, please visit: https://github.com/wa1gon/aclogGate/tree/master/server logRouter.get("/loggate/v1/listall", function(req, res) { let ...

Struggling to dynamically update array values by comparing two arrays

I am faced with a scenario where I have two arrays within an Angular framework. One of the arrays is a regular array named A, containing values such as ['Stock_Number', 'Model', 'Type', 'Bill_Number'] The other arr ...

What is the process for adjusting the color of axes in vue-chartjs?

Seeking help on how to adjust the color of the axis in my graph. Has anyone encountered a similar issue before? The chart I'm working with resembles the one shown in the image. Not sure if this issue is related to it being a time graph. Below is the V ...

What type is the appropriate choice for this handler?

I´m struggling to select the right type for this particular function. It serves as an async handler for express js in a project that utilizes typescript and eslint for linting with specific rules. export function asyncHandler( handler: any ): (req: Requ ...

Saving a JSON object to multiple JSON objects in TypeScript - The ultimate guide

Currently, I am receiving a JSON object named formDoc containing data from the backend. { "components": [ { "label": "Textfield1", "type": "textfield", "key": "textfield1", ...

Error: Could not find module: Unable to locate 'rxjs/add/observable/throw' in 'D:AngularhttpErrorHandlingExamplesrcapp'

I'm working on an Angular project to practice error handling, but I encountered an issue when trying to import the 'throw' module. The error message reads as follows: Error Message: "ERROR in ./src/app/employee.service.ts Module not found: E ...

The Typescript intellisense feature in VS Code seems to be malfunctioning

While setting up typings for my Node server, the intellisense suddenly stopped working. I checked my tsconfig.json file: { "version": "0.1.0", "command": "tsc", "isShellCommand": true, "args": ["-p", "."], "showOutput": "silent", " ...