Validate an array of strings using Typescript custom type

Recently, I attempted to verify whether a variable is a custom type made up of different strings. I came across this helpful post Typescript: Check "typeof" against custom type that explains how to create a validator for this specific type.

const fruit = ["apple", "banana", "grape"];
export type Fruit = (typeof fruit)[number];
const isFruit = (x: any): x is Fruit => fruit.includes(x);

One part I'm struggling to understand is this instruction:

(typeof fruit)[number]

Can someone explain how this works? I know that typeof is Typescript's query type, but the [number] part is confusing to me. It's meant to "define your Fruit type in terms of an existing array of literal values."

Answer №1

Upon examining the type for typeof fruit, you will find:

type AllFruit = ['apple', 'banana', 'grape'];
.

If you wish to achieve this result, you may have to designate the array as readonly (e.g.

const fruit = <const>['apple', 'banana', 'grape'];
).

This type can be indexed as follows:

type Apple = AllFruit[0]; // 'apple'
type Grape = AllFruit[2]; // 'grape'

type AppleGrape = AllFruit[0 | 2]; // 'apple' | 'grape'

Therefore, the [number] essentially indexes every value in the array:

type Fruit = typeof fruit[0 | 1 | 2]; // 'apple' | 'banana' | 'grape'
type Fruit = typeof fruit[number]; // 'apple' | 'banana' | 'grape'

I hope this explanation is helpful.

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

Exploring the functionalities of TypeScript's mapKey and pick features

I am looking to convert the JavaScript code shown below into TypeScript, but I don't want to use loadish.js. let claimNames = _.filter<string>(_.keys(decodedToken), o => o.startsWith(ns) ); let claims = <any>( _.mapKeys(_ ...

The sticky navbar fails to stay in place when the content becomes too lengthy

This is my current state of code (minified, for explanation only) index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-w ...

What steps should I take to address the numerous errors I am encountering in Atom using the Atom linter tool?

My Atom interface is showing the following errors: {Error running gjslint}(x4) {Error running selective}(x4) Upon checking the errors section, I found the following details: [Linter] Error running selective Error: ENOENT: no such file or directory, open ...

Tips for splitting JSON objects into individual arrays in React

I'm currently tackling a project that requires me to extract 2 JSON objects into separate arrays for use within the application. I want this process to be dynamic, as there may be varying numbers of objects inside the JSON array in the future - potent ...

How can I invoke a TypeScript function within HTML code?

Currently, I am working on an Angular project where I have implemented two straightforward methods in a TypeScript file: findForm(text: string, forms: Array<string>) { for (let form of this.forms) { if (text.includes(form)) { retur ...

Issue with implementing MUI Style Tag in conjunction with styled-components and Typescript

I have created a custom SelectType component using Styled Components, which looks like this: import Select from '@mui/material/Select'; export const SelectType = styled(Select)` width:100%; border:2px solid #eaeaef; border-radius:8px ...

Combine two arrays into one

When attempting to combine two arrays, the result looks like the image linked below: https://i.sstatic.net/3FWMZ.png I want the merged array to resemble the following example: {0: {…}, storedArr: Array(2)} 0: address: "ifanio de los Santos Ave, Ma ...

The functionality of MaterializeCSS modals seems to be experiencing issues within an Angular2 (webpack) application

My goal is to display modals with a modal-trigger without it automatically popping up during application initialization. However, every time I start my application, the modal pops up instantly. Below is the code snippet from my component .ts file: import ...

Tips for Validating Radio Buttons in Angular Reactive Forms and Displaying Error Messages upon Submission

Objective: Ensure that the radio buttons are mandatory. Challenge: The element mat-error and its content are being displayed immediately, even before the form is submitted. It should only show up when the user tries to submit the form. I attempted to use ...

Having trouble retrieving the "history" from props?

I am working with a React component. import * as React from 'react'; import { Component } from 'react'; import { FormControl, Button } from 'react-bootstrap'; type Props = { history: any[]; }; // Question on defining Prop ...

Unable to generate paths in Ionic 3

I am trying to view the actual route on the URL, but I'm having trouble figuring out exactly what needs to be changed. I've been referring to the documentation at: https://ionicframework.com/docs/api/navigation/IonicPage/ However, I keep encoun ...

Is Angular2 detecting changes based on value equivalence or reference equality?

I am currently working with Angular2-RC.1 and I've noticed a significant decrease in performance when setting up a component with a large dataset. The component I'm using is a tabular one (which involves Handsontable) and it has an Input property ...

Exploring the contrast between string enums and string literal types in TypeScript

If I want to restrict the content of myKey in an object like { myKey: '' } to only include either foo, bar, or baz, there are two possible approaches. // Using a String Literal Type type MyKeyType = 'foo' | 'bar' | &ap ...

Navigating resolvedUrl with getServerSideProps in the newest version of NextJS - a comprehensive guide

Is there a way to obtain the pathname without using client-side rendering? I have been searching for information on how to utilize the getServerSideProps function, but so far with no luck. Initially, I attempted to employ usePathname; however, this result ...

An issue with the Pipe searchByType is resulting in an error stating that the property 'type' is not found on the type 'unknown'

I keep encountering a range of errors like roperty does not exist on type 'unknown' after running the command ionic build --prod --release src/app/pages/top-media/top-media.page.ts:18:16 18 templateUrl: './top-media.page.html', ...

How to process response in React using Typescript and Axios?

What is the proper way to set the result of a function in a State variable? const [car, setCars] = useState<ICars[]>([]); useEffect(() =>{ const data = fetchCars(params.cartyp); //The return type of this function is: Promise<AxiosRespo ...

Click to Rotate Angular Chevron

Is it possible to animate the rotation of a chevron icon from left-facing to right-facing using Angular? CSS: .rotate-chevron { transition: .1s linear; } HTML: <button [class.button-open]="!slideOpen" [class.button-close]="slideOpe ...

Angular2 - receiving an error message stating that this.router.navigate does not exist as a

Currently, I am delving into the world of Angular2 with Ionic and working on crafting a login page. However, upon loading the page, an error surfaces: 'router.initialNavigation is not a function' To address this issue, I inserted '{initialN ...

Using TypeScript to extract types from properties with specific types

My current challenge involves working with a filter object derived from an OpenAPI spec. The structure of this object is illustrated below: export interface Filters { field1: string[] field2: string[] field3: boolean field4: number } My goal is to ...

Tips for customizing standard data types in TypeScript

Currently facing a challenge where I need to update a global type. Specifically, I am looking to modify the signature of the Element.prototype.animate function to make it optional. This is the approach I attempted: declare global { interface Element { ...