Obtain enumeration from an Array with limitations on data type

This is similar to extract property values from array, however, in this case, the type of array needs to be restricted as well.

Consider the following example:

type ElemProp = {id: number, name: string, quickFormat?: boolean }

const formatList:ElemProp[] = [
    {id:1, name: 'ABC'},
    {id: 3, name: 'XYZ'},
    {id: 98, name: 'GOGOGO', quickFormat: true}
] as const

type IdEnum = (typeof formatList)[number]['id']

The IdEnum value is determined as number instead of 1|3|98.

However, removing :ElemProp[] would result in getting the enum, but it will lead to losing all type support.

The question arises: how can one obtain the enum while still maintaining type support for the original array?

Attempts have been made to change things to readonly, add as const, yet as long as the ElemProp[] remains, IdEnum continues to return number.

Post-answer update:

The main goal here was to restrict the types of paragraph styles provided to paragraphs when utilizing https://github.com/dolanmiu/docx/ for creating docx files in NodeJS. Although it may not seem very refined at present, there are insights into its potential growth.

import dx from 'docx';
import { IPropertiesOptions } from 'docx/build/file/core-properties';

type StylesAndNumberings = Required<Pick<IPropertiesOptions, 'styles' | 'numbering'>>; // for reference only

export type ExtractParagraphIds<U extends Partial<IPropertiesOptions>> = U extends {
    readonly styles: { readonly paragraphStyles: infer U extends readonly { id: string }[] };
}
    ? U[number]['id']
    : never;

const docProps = {
  styles: {
    paragraphStyles: [
      {
        id: 'normal',
        name: 'Normal',
        basedOn: 'Normal',
        next: 'Normal',
        quickFormat: true,
        run: {
          font: 'Arial',
          size: 22,
        },
      }]
  }
} as const satisfies Partial<IPropertiesOptions>;

type IdEnum = ExtractParagraphIds<typeof docProps>;

export const textToParagraph = <T extends Partial<IPropertiesOptions>>(
    t: string,
    runFormat: dx.IRunOptions = {},
    paragraphOptions: dx.IParagraphOptions & { style?: ExtractParagraphIds<T> } = {},
    paragraphFreeChildren: dx.IParagraphOptions['children'] = []
) => {
    const text = t.split('\n');
    if (text.length === 1) {
        return new dx.Paragraph({
            wordWrap: true,
            children: [
                new dx.TextRun({
                    text: t,
                    ...runFormat,
                }),
                ...paragraphFreeChildren,
            ],
            ...paragraphOptions,
        });
    }
    return new dx.Paragraph({
        children: [
            ...text.map((line, i) => {
                return new dx.TextRun({
                    text: line,
                    ...runFormat,
                    break: i ? 1 : 0,
                });
            }),
            ...paragraphFreeChildren,
        ],
        ...paragraphOptions,
    });
};

Answer №1

Utilize the satisfies keyword:

type ElemProperty = {identifier: number, label: string, speedyFormat?: boolean }

const propertyList = [
    {id:1, name: 'ABC'},
    {id: 3, name: 'XYZ'},
    {id: 98, name: 'GOGOGO', speedyFormat: true}
] as const satisfies ElemProperty[];

type EnumId = (typeof propertyList)[number]['id']

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

Guide to uploading files in Vue.js v3

I'm trying to implement file upload functionality using Vue.js version 3. Although I have successfully imported ref, I am unsure how to utilize it for retrieving file data? FileUploadTest.vue <template> <h1>File Upload</h1> <div ...

What is the process for converting a .ts file to a .js file within a Next.js project for Web worker implementation?

I am currently working on a TypeScript Next.js project: "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint& ...

Angular directive to delete the last character when a change is made via ngModel

I have 2 input fields where I enter a value and concatenate them into a new one. Here is the HTML code: <div class="form-group"> <label>{{l("FirstName")}}</label> <input #firstNameInput="ngMode ...

Getting the data from the final day of every month in a Typescript time-series object array

I am dealing with timeseries data retrieved from an API that consists of random dates like the following: [ { "id": 1, "score": 23, "date": "2023-08-30" }, { "id": 2, "score&qu ...

How can I enable editing for specific cells in Angular ag-grid?

How can I make certain cells in a column editable in angular ag-grid? I have a grid with a column named "status" which is a dropdown field and should only be editable for specific initial values. The dropdown options for the Status column are A, B, C. When ...

The function 'ShouldWorkController' was expected but is not defined, receiving undefined instead

Whenever I attempt to connect a controller to a template using the angular-ui-router $stateProvider, I encounter this error message: 'ShouldWorkController' is not a function. Got undefined. Surprisingly, when I define the controller within the ...

The error message "VueRouter does not have a property named 'history'" is common in Vue with TypeScript

In my typescript vue application, I encountered an error within a component while trying to access a parameter passed into the route. Here is the relevant code snippet: properties = getModule(PropertiesModule, this.$store); mounted() { id = this.$router. ...

What steps should I take to enable TypeScript IntelliSense to recommend correct suggestions within discriminated unions?

I am working on creating a checkbox UI component based on a design in Figma. The outline variant is specified to only be compatible with the large size, while the solid variant can be used with all sizes. As a result, I am trying to build an interface whe ...

Having trouble getting TypeScript to install using npm on a Mac?

My goal is to use Typescript as a local dependency by checking it into my devDependencies and using it via an npm script after installing it with 'npm install'. However, when I try this on my machine, I find that Typescript (and webpack-cli as w ...

Validation of parameter data types in Typescript

I need help differentiating between React.MouseEvent and React.KeyboardEvent in my TypeScript component foo(e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) { if(e is mouse event) { //do something } else ...

I am attempting to update the URL of an iframe dynamically, but I am encountering an issue: the Error message stating that an Unsafe value is being

Currently, I am attempting to dynamically alter the src of an iframe using Angular 2. Here is what I have tried: HTML <iframe class="controls" width="580" height="780" src="{{controllerSrc}}" frameborder="0" allowfullscreen></iframe> COMPONE ...

Is there a way to display the items I've added to my cart when I click on it?

I have a collection of product IDs stored in local storage. I am using these IDs to populate the list of products added to the basket. Strangely, when I navigate to the basket page, the products do not appear unless I make a small code modification or re-s ...

When defining properties/data in Vue mixins, the properties/data of the mixin are not accessible

A vue mixin is being used to store information (referred as `world` in the example below) that needs to be accessed in multiple vue components without having to import it every time. Check out the code snippet: <template> <ol> <li> ...

Error message: "The property is not found within the specified type when using the OR operator with

Within my Angular component, I am faced with a challenge involving an Input that can be one of two types. @Input() profile: UserProfileDetails | BusinessProfileDetails; The structure of the profile template is straightforward and I want to avoid duplicati ...

Unable to change the directory for angular2/core - having issues with updating

Whenever I include the following code in my app.component.ts: import {Component} from 'angular2/core'; My application runs successfully, but the compiler throws an error saying Error:(1, 25) TS2307: Cannot find module 'angular2/core', ...

Bringing in additional types with the primary import using import/require

I am currently creating a definition file for Airtable, and I have encountered an issue with the way they export their classes. They only provide one class like this: ... module.exports = Airtable; As a result, my airtable.d.ts file looks something like ...

Issue with Zend LiveDocx - Unable to access template file on local disk

I've been facing an issue while attempting to generate a word document in my Zend Framework project. Below is the code snippet for my action: public function createwordAction(){ $this->_helper->layout->disableLayout(); $this->_he ...

Form validation errors were detected

Currently, I am working with a formgroup that contains input fields with validations set up in the following manner: <mat-form-field class="mat-width-98" appearance="outline"> <mat-label>Profession Oc ...

Issue encountered during rendering: "TypeError: Attempting to access property '_t' of an undefined object" while running a Unit Test using Jest

I spent hours troubleshooting a unit test for my Vue.js component, but no matter how much I searched the internet, I kept encountering this error: console.error node_modules/vue/dist/vue.runtime.common.dev.js:1884 TypeError: Cannot read property ' ...

Creating a personalized Angular component from an external library that can be activated with the "enter" key

The issue at hand Summary: I am encountering a problem with an angular component that is not clickable using the "Enter" key. I have developed a library using stencil that contains and produces various angular components to be utilized across multiple ap ...