A guide on creating a function that can detect if an object is not iterable and then throw an error

Exploration

Uncomfortable type definition at the library:

declare type Extension = {
    extension: Extension;
} | readonly Extension[];

Type-validation function

export function isIterable(x: any): x is Iterable<unknown> {
  return Symbol.iterator in x;
}

Solution Implementation

Utilizing the type-validation function

const extensions:Extension = getExtensions();
if (!isIterable(extensions)) { // Validation
  throw Error('extensions should be iterable');
}
console.log(...extensions); // Executing successfully

Dilemma

Efforts to devise a Helper function for Type-checking:

import { isIterable } from '../type-guarded/isIterable';

export const throwIfNotIterable = <T,>(value: T) => {
  if (isIterable(value)) {
    return value;
  }

  throw TypeError(
    `Expected to be iterable, but received ${value} (${typeof value})`
  );
};

Note: Inferred type:

const throwIfNotIterable: <T>(value: T, name: string) => T & Iterable<unknown>;

Trial and Error

Attempt 1

console.log(...throwIfNotIterable(extensions));

ERROR:

Type 'unknown' cannot be assigned to type 'Extension'.

Attempt 2

throwIfNotIterable(extensions, 'not iterable');
console.log(...extensions);

ERROR:

Type 'Extension | undefined' should have a '[Symbol.iterator]()' method that provides an iterator.

Seeking insight on my errors?

Answer №1

To transform your throwIfNotIterable function into an assertion function, consider renaming it to assertIsIterable as is common practice for assertion functions:

export function assertIsIterable<T>(
    value: T | Iterable<unknown>
): asserts value is Iterable<unknown> {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    if (!isIterable(value)) {
        throw TypeError(`Expected to be iterable, instead got ${value} (${typeof value})`);
    }
}

// ...

const extensions: Extension = getExtensions();
assertIsIterable(extensions);
console.log(...extensions); // Works

Playground example

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

Error in TypeScript: The property 'data' is not found within type '{ children?: ReactNode; }'. (ts2339)

Question I am currently working on a project using BlitzJS. While fetching some data, I encountered a Typescript issue that says: Property 'data' does not exist on type '{ children?: ReactNode; }'.ts(2339) import { BlitzPage } from &q ...

When executed, the Node application successfully compiles

I have a TypeScript application that runs smoothly in development mode using ts-node. However, after building the application, I encounter some unexpected warnings and errors. This is my tsconfig.json: { "compilerOptions": { "incremen ...

Definition of a Typescript Global.d.ts module for a function that is nested within another function

Simply put, I have a npm module that exports a function along with another function attached to it: // @mycompany/module ... const someTool = (options) => { // do some cool stuff }; someTool.canUseFeature1 = () => { return canUseSomeFeature1(); ...

Establishing the value of "document.cookie"

Encountering issues while trying to set a cookie using different methods: Method 1: document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; path=/"; This method only sets the value up to "name=value" wh ...

What is the process of creating an asynchronous function that will resolve a promise when the readline on('close') event is triggered within it in Typescript?

Here's a code snippet I'm working with: private readFile() { var innerPackageMap = new Map<string, DescriptorModel>(); // Start reading file. let rl = readline.createInterface({ input: fs.createReadStream(MY_INPUT_FILE ...

A guide to updating a table in Angular using an API response

My form allows me to select events from a drop-down list and choose a date. Depending on the selected date, it retrieves the number of events that occurred on that specific date. If I select an event and a date where events took place, the "All Events" sec ...

Updated the application to Angular 6 but encountered errors when attempting to run npm run build --prod. However, running the command npm run build --env=prod was executed without any issues

Running the command npm run build -- --prod results in the following error messages: 'PropertyName1' is private and can only be accessed within the 'AppComponent' class 'PropertyName2' does not exist in type 'AppCompo ...

Eliminate the hashtag (#) from the URL in Angular 11

I am facing an issue with removing the # from the URL. When I try to remove it, the application encounters a problem upon deployment to the server. Upon page refresh, a 404 error status is returned. For instance: https://example.com/user/1 (works) https ...

Aligning validation schema with file type for synchronization

Below is the code snippet in question: type FormValues = { files: File[]; notify: string[]; }; const validationSchema = yup.object({ files: yup .array<File[]>() .of( yup .mixed<File>() .required() .t ...

Change the spread operator in JavaScript to TypeScript functions

I'm struggling to convert a piece of code from Javascript to Typescript. The main issue lies in converting the spread operator. function calculateCombinations(first, next, ...rest) { if (rest.length) { next = calculateCombinations(next, ...res ...

Navigating SSL certificate prompts in Protractor

Our programs utilize SSL certificates and we are unable to bypass Chrome's prompt for selecting a certificate. We would be satisfied with simply choosing the one certificate needed. Attempts have been made using this code: capabilities: { browser ...

Adding an Icon to the Angular Material Snackbar in Angular 5: A Step-by-Step Guide

I recently started using Angular and have incorporated Angular Material Design for my UI elements. Within my application, I am utilizing a snackbar component. However, I am facing difficulty in adding an icon inside the snackbar despite trying various so ...

Tips for addressing style issues within innerText

I am trying to use PrismJS to highlight HTML code, but the inner text function doesn't recognize line breaks (\n). <pre class="language-markup background-code"><code [innerText]="getHtmlCode()""></code> I have been working wi ...

Is it possible to utilize pinia getter as the initial parameter in Vue3's watch function?

Issue Recap In Vue3, can Pinia getters be utilized as a watch target's first argument? System Details Vue version: 3.2.13 Pinia version: 2.1.4 TypeScript version: 4.5.5 Problem Description An error was encountered when attempting to reference the ...

What is the most efficient way to iterate through an array to push properties into an object nested within another array?

I have been working on a small Angular application that functions as a scheduler, allowing users to input a Name, Start and End dates, and toggle a boolean checkbox through a form. One challenge I am facing is trying to assign the names entered by each use ...

Troub3leshooting Circular Dependency with Typescript, CommonJS & Browserify

I am currently in the process of transitioning a rather substantial TypeScript project from internal modules to external modules. The main reason behind this move is to establish a single core bundle that has the capability to load additional bundles if an ...

Angular 6 component experiencing issues with animation functionality

I've implemented a Notification feature using a Notification component that displays notifications at the top of the screen. The goal is to make these notifications fade in and out smoothly. In my NotificationService, there's an array that holds ...

Can you explain the concept of static in Typescript?

Exploring the distinctions between the static and instance sides of classes is addressed in the Typescript documentation on this page. The static and instance sides of classes: understanding the difference In object-oriented programming languages like ...

Angular 6 introduces a new component with cascading comboboxes for easier data organization

In my Angular 6 project, I have successfully implemented a shared component called country-state. It is functioning perfectly. VIEW MY PERFECT WORKING EXAMPLE However, upon dividing the country-state component into separate country and state components, ...

What is the best way to extract value from subscribing?

I attempted to accomplish this task, however, I am encountering issues. Any assistance you can provide would be greatly appreciated! Thank you! export class OuterClass { let isUrlValid = (url:string) => { let validity:boolean ...