Creating nameless entities in Typescript without resorting to type declarations

Take into account the following code snippet:

type Example = {
   prop1: string,
   prop2: number
}

const values = ['x', 'y', 'z'];
const examples = values.map<Example>((val, i) => {
   return {
     prop1: val,
     prop2: i
   }
});

This will not strictly enforce the type of the return value from the map function. For instance, you could do this:

return {
  prop1: val,
  prop2: i,
  extraProperty: 'test'    // This is allowed! (undesired behavior)
}

This behaves similarly to using a generic type and applying a type assertion on the return value like this:

return {
  prop1: val,
  prop2: i,
  extraProperty: 'test'   // allowed (undesirable)
} as Example

The only method I have found to fully enforce the type is by creating an intermediary variable:

const resultValue: Example = {
  prop1: val,
  prop2: i,
  // extraProperty: 'test' // Compiler error - TypeScript catching mistakes!
}
return resultValue;

Is there any syntax that enables creating an anonymous object in the return statement while completely enforcing the type, instead of just using a type assertion?

Answer №1

The issue arises from the fact that object literals are only checked for excess properties when they are directly assigned to a parameter, variable, or return value. Even though you specify the type parameter on map, the arrow function will initially be typed with this signature:

(bar: string , i: number) => {    
    bar: string,
    baz: number,
    extraProp: string
}

Subsequently, this function is evaluated for compatibility with the map argument (typed as

(bar: string , i: number) => Foo
) and deemed compatible.

An easy solution is to define the type not on map but on the return type of the arrow function :

const foos = bars.map((bar, i): Foo => {
    return {
        bar,
        baz: i,
        extra: "" // error here, as expected
    }
});

This is not a form of type assertion, rather it necessitates specifying the type, which ends up being done on map anyway; thus, the typing effort remains consistent.

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

The onSubmit function in Formik fails to execute if there are no input values present

I am currently working on building a form using Next.js, TypeScript, and the Formik + Yup libraries. I've encountered two scenarios: one where an input field is visible and Formik captures the value, and another where the input is not visible and the ...

Tips for automatically increasing the ID of a parameter in Angular using TypeScript

I am working on creating a gallery using the @ks89/angular-modal-gallery library, and the only remaining task is to assign different ids to each image in the gallery. I attempted to use a for loop, but it returned undefined. https://i.sstatic.net/7TmEN.pn ...

A hiccup occurred during the execution of the Node.js application due to a TypeScript file

Here are the errors that have been encountered: D:\agent-master>npm run build > <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="472620222933077769766977">[email protected]</a> build D:\agent-ma ...

I rely on the angular-responsive-carousel library for my project, but unfortunately, I am unable to customize the arrow and dots

When it comes to CSS, I utilize ng deep style in Angular 10 to make changes for browser CSS. However, I am facing an issue where the problem is not being resolved by my CSS code. Here is a snippet of my code: > ::ngdeep .carousel-arrow { > b ...

Converting a TypeScript class to a plain JavaScript object using class-transformer

I have a few instances of TypeScript classes in my Angular app that I need to save to Firebase. However, Firebase does not support custom classes, so I stumbled upon this library: https://github.com/typestack/class-transformer which seems to be a good fit ...

Creating a loading screen in Angular 4: Insert an item into the HTML and then set it to disappear automatically after

I'm dealing with a loading screen that typically takes between 15-30 seconds to load about 50 items onto the page. The loading process displays each item on the page using the message: Loading item x For each data call made to the database, an obser ...

Exploring the parent-child relationship of three components within Angular 2

Currently, I am developing a shopping cart using Angular 2. The application consists of two components - one for categories and another for product listings, both included in the main app component as children. However, I'm facing an issue where these ...

ReactJS Provider not passing props to Consumer resulting in undefined value upon access

Hey there! I've been facing an issue with passing context from a Provider to a consumer in my application. Everything was working fine until suddenly it stopped. Let me walk you through a sample of my code. First off, I have a file named AppContext.t ...

I am currently working on creating my website on CloudFlare with the help of React.JS

Struggling with a website build issue while using the Git repo on Cloudflare. Despite attempting various solutions like deleting yarn.lock, running yarn cache clean -all, and then yarn install, I keep encountering the same error. Since I am relatively new ...

Combine a collection of promises into a single promise that may contain either strings or numbers: [P<string>, P<number>] -> Promise<string | number>

I'm currently working on a function that aims to retrieve the first resolved value from an array of Promises const findFirstResolvedValue = (...promises: Array<Promise<any>>): Promise<any> { // ... } const result = findFirstResol ...

What is the best way to send props (or a comparable value) to the {children} component within RootLayout when using the app router in Next.js

As I work on updating an e-commerce website's shopping cart to Next.js 13+, I refer back to an old tutorial for guidance. In the previous version of the tutorial, the _app.ts file utilized page routing with the following code snippet: return ( < ...

What could be the reason for the tsc command not displaying compilation errors when compiling a particular file?

My file, titled app.ts, contains the following code snippet: interface Foo { bar:String; } const fn = (foo? :Foo) => foo.bar; When I run tsc from the root folder with strict:true in my tsconfig.json file, I receive an error message like this ...

Implement the CSS styles from the Parent Component into the Child Component using Angular 6

Is there a way to apply CSS from the Parent Component to style the child component in Angular 6? Please advise on how to approach this issue. How can we inherit the css styles from the Parent Component? <parent> <child> <p>hello ...

I find myself hindered by TypeScript when trying to specify the accurate constraints for getUserMedia

I'm having difficulty getting a screen to stream within my Angular 5 Electron application. I am utilizing the desktopCapturer feature provided by Electron. Below is an excerpt of my code: loadCurrentScreensource() { desktopCapturer.getSources({ ...

Adjust the size of an Angular component or directive based on the variable being passed in

I'm looking to customize the size of my spinner when loading data. Is it possible to have predefined sizes for the spinner? For example: <spinner small> would create a 50px x 50px spinner <spinner large> would create a 300px x 300p ...

Is it possible to implement websockets with inversify-express-utils?

We are attempting to integrate websockets into our typescript application built on inversify-express-utils, but so far we have had no success: import 'reflect-metadata'; import {interfaces, InversifyExpressServer, TYPE} from 'inversify-expr ...

Can a reducer be molded in ngrx without utilizing the createReducer function?

While analyzing an existing codebase, I came across a reducer function called reviewReducer that was created without using the syntax of the createReducer function. The reviewReducer function in the code snippet below behaves like a typical reducer - it t ...

The 'import.meta' meta-property can only be used with the '--module' set to 'es2020', 'esnext', or 'system'.ts(1343)

Whenever I attempt to utilize import.meta.url (as demonstrated in the Parcel docs), I am consistently met with the error message "The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es ...

Create a custom class that functions similarly to a dictionary

Is it not feasible to achieve this? interface IMap { [key: string]: string; } class Map implements IMap { public foo = "baz"; } But instead of success, I encounter the error: TS2420:Class 'Map' does not correctly implement 'IMap& ...

Creating a component inventory in ReactJS is inefficient and causes delays

With a list of components ranging from 50 to 100, each containing numerous child elements, the process of rendering them requires significant effort. This leads to a noticeable delay of 1-2 seconds when navigating to the page, with the UI essentially free ...