Enable a fraction of a category

Imagine having a structure like this

interface User {
  name: string;
  email: string;
}

along with a function like this

updateUser(user: User) {
}

As currently defined, updateUser cannot accept only a name (updateUser({name: 'Anna'} would fail) if that is the sole property intended for updating.

Making email optional in the User interface could solve this issue, but it's not an ideal solution. The expectation should be that when someone receives a User object, all fields are present. One possible solution is to change the type of updateUser to:

updateUser(user: {name?: string, email?: string}) {
}

This approach works, but requires repeating the entire user object and updating both declarations whenever new properties are added to the User interface.

Is there a way to define updateUser so that it allows specific parts of a user object, while still rejecting missing or incorrectly typed properties?

Answer №1

When dealing with assertions in this scenario, using the <User> assertion like so is an option:

updateUser(<User>{name: 'Anna'})
updateUser(<User>{email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="12617d7f7752737c7c733c717b1e79737975771c707c7e">[email protected]</a>'})

However, utilizing nullability would be a better approach as it ensures only valid properties are passed through:

interface IUser {
  name?: string;
  email?: string;
}

With TypeScript 1.6, we have certainty that the following will succeed:

interface IUser {
  name?: string;
  email?: string;
}

function updateUser2(user: IUser) {
}
// Objects of type IUser
updateUser2({name: 'Anna'})
updateUser2({email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c8bba7a5ad88a9a6a69aa5afaefbfcd1bea2a0a3a685abaaa3a2abeea3afad">[email protected]</a>'})

Conversely, this will fail:

// Not of type IUser
updateUser2({wrongProperty: 'someValue'})

Test it out on the typescript playground

Further information: New features in TypeScript

Enhanced object literal assignment checks

In TypeScript 1.6, stricter rules for object literal assignments are imposed to prevent incorrect or excess properties. Specifically, assigning a new object literal to a variable with a defined structure will produce an error if the object contains properties not present in the target type. Examples

var x: { foo: number };
x = { foo: 1, baz: 2 };  // Error, additional property `baz`

var y: { foo: number, bar?: number };
y = { foo: 1, baz: 2 };  // Error, extra or misspelled property `baz`

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

Angular is unable to iterate through a collection of ElementRef instances

My list of ElementRef contains all my inputs, but adding listeners to them seems to indicate that textInputs is empty even though it's not. @ViewChildren('text_input') textInputs!: QueryList<ElementRef>; ngAfterViewInit(): void { ...

What's the best way to add animation to the send icon while hovering over the button?

<div class="text-center"> <button [disabled]="btnStatus" class="btn btn-secondary buttonSend" type="submit"> <div [hidden]="btnStatus"> Send Message&nbsp;&nbs ...

Guide to generating a text string by utilizing the foreach loop

Is there a way to combine text strings from interfaces into a single file for display in UI? The current code is generating separate files for each interface. How can I achieve the expected result of having all interfaces in one file? Additionally, is it ...

Ensure the JSON file aligns with the TypeScript Interface

I am working with a config.json file. { "profiler": { "port": 8001, "profilerCache": { "allowedOriginsRegex": ["^http:\/\/localhost:8080$", "i"] } }, "database": { "uri": "mongodb+srv://...", "dbName": "profiler", ...

Can a standard tuple be matched with its corresponding key?

This code snippet showcases a function that can recognize that the key "banana" cannot have the value "red": type Fruits = { banana: 'yellow' | 'green' strawberry: 'red' } const fruit = <K extends keyof Fruits>(modu ...

Unable to find custom components when using react-router

My goal is to improve the organization of my Routes in React and separate concerns. I am currently utilizing react-router-dom version 5. Within my Application Routes component, I have structured it with 3 children components: AuthenticatedRoutes PublicRo ...

Is it possible to meet the requirements of a specific interface using an enum field as the criteria?

I've been struggling to create a versatile function that can return a specific interface based on an enum argument, but all my attempts have failed. Could it be possible that I missed something or am simply approaching it the wrong way? If I try to ...

Pausing in a NodeJS HTTP request listener until receiving another response before proceeding

Essentially, this is a web proxy. Within a request listener, I am creating another http request, reading its response, and passing it to the main response. But I have the challenge of needing to wait for the secondary request to complete before continuing. ...

When working with TypeScript, encountering an error involving an array containing an index signature

When attempting to change an object's type to a generic array using the as keyword, I encountered an error. interface TestType { action: TestGeneric<number>[] } type TestGeneric<T> = { [key: string]: T } const func = () => { ...

Exploring how process.argv in NodeJS can be utilized within JavaScript code compiled by

I'm having trouble compiling a basic TypeScript file using webpack (with 'awesome-typescript-loader') that needs to access command line arguments. It seems like the compiled JavaScript is causing a problem by overriding the Node 'proce ...

Encountering difficulty invoking a component method from d3's call() function

My current setup involves using D3 to drag and drop links in the following manner: .call(d3.drag() .on("start", linkDragStart) .on("drag", linkDragging) .on("end", linkDragEnd)); Recently, I decided to extract this functionality into a separate met ...

Missing "this" after initialization? (typescript/node/express)

I am currently working on creating a basic http application using node-express. One issue I encountered is that when setting up routes, the constructor of the MyRouter class has access to this, but it seems to be lost within the getRoutes() function. cla ...

Searching for variables within files using Node.js and constructing an object from the results

Trying to figure out how to streamline this process. Here's the directory structure I'm working with: src/ modules/ clients/ i18n/ en-US.ts tasks/ i18n/ en-US.ts So, ea ...

The input tag loses focus after its value is updated using a class method in Angular 8.x

Currently, I am working on integrating a credit card payment method and formatting its number through specific methods. Here is how it is done: HTML <div class="form-group" *ngFor="let formField of cardFields; let cardFieldIndex = index;"> ...

Preventing an Angular component from continuing to execute after clicking away from it

At the moment, I have a sidebar with clickable individual components that trigger API calls to fetch data. However, I've noticed that even when I click off a component to another one, the old component continues to refresh the API data unnecessarily. ...

The express application's GET route is causing a "Cannot GET" error to be thrown

I am managing different types of pages: the main root page (/) today's chapter page (/929 OR /929/) which eventually redirects to /929/<CHAPTER> where <CHAPTER> is a natural number between 1 to 929 individual chapter pages (/929/<CHAP ...

I am unable to utilize the Web Share API for sharing a file within my React app written in TypeScript

Trying to launch a WebApp for sharing files has been quite a challenge. After some thorough research, I stumbled upon the Web Share API which seemed like the perfect solution based on standard practices. The documentation provided a clear outline of how it ...

Encountering an error in Angular 4: 'Cannot find property on specified component type'

I recently embarked on the journey of learning Angular 4 and TypeScript, but I've encountered my first obstacle. My current challenge involves creating a simple date and time component. Despite having a seemingly correct Javascript code, I believe I ...

Looking to transform a timestamp such as "2021-07-18T9:33:58.000Z" into a more readable format like 18th July for the date or 9:33 am for the time using Angular?

Is there a way to convert the Timestamp format "2021-07-18T9:33:58.000Z" to display as 18th July (for date) or 9:33 am (for time) in an Angular 11 application? Currently, my code looks like this: const myDate = new DatePipe('en-US').transform ...

The type '{ children: Element[]; }' does not include the properties 'location' and 'navigator' that are present in the 'RouterProps' type

Struggling to implement React Router V6 with TypeScript, encountering a type error when including Routes within the `<Router />` component. The error message indicates that the children property passed to the Router is of an incorrect type, despite u ...