Mapped TypeScript type requiring scalar properties and allowing optional objects

I am in need of a TypeScript generic type that has the capability to alter another type so that all scalar properties (such as strings, numbers, booleans, etc.) remain mandatory, while object types become optional.

For instance, given the User type below, I would like name and age to be obligatory, but for address to be made optional.

type User = {
  name: string;
  age: number;
  address: {
    street: string;
    postcode: string;
  };
};

Answer №1

As I was formulating this query, the solution dawned on me. It's amazing how helpful StackOverflow can be!

type ScalarTypes = string | number | boolean | Date;
type OptionalObjects<T> = {
  [P in keyof T as T[P] extends ScalarTypes ? P : never]: T[P];
} & {
  [P in keyof T as T[P] extends ScalarTypes ? never : P]?: T[P];
};

// this example is acceptable
const partialUser: OptionalObjects<User> = {
  name: "Me",
  age: 12,
};

// this scenario is also valid
const fullUser: OptionalObjects<User> = {
  name: "Me",
  age: 12,
  address: {
    street: "My Street",
    postcode: "AB123",
  },
};

// @ts-expect-error this will throw an error since name and age are missing
const emptyUser: OptionalObjects<User> = {};

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

Unexpected behavior encountered when using TypeScript type declarations

I am currently working on a Gatsby side project incorporating Typescript for the first time. I initially expected Typescript to behave similarly to PHP type declarations, but I have encountered some unforeseen issues. Despite feeling confident in my Typesc ...

Are my Angular CLI animations not working due to a version compatibility issue?

I've been working on a project that had Angular set up when I started. However, the animations are not functioning correctly. The mat input placeholder doesn't disappear when typing, and the mat-select drop-down is not working. Here is my packag ...

Angular2-starter configuration setup with environment-based variables (such as .env or .conf) for testing and production settings

Frameworks like PHP Laravel often include files for local configuration, separate from dev, test, and production environments. How can a configuration file be provided for an angular-starter project that contains all local environment variable values (su ...

When running the test, a "is not defined" ReferenceError occurs in the declared namespace (.d.ts) in ts-jest

When running typescript with ts-jest, the application functions properly in the browser but encounters a ReferenceError: R is not defined error during testing. The directory structure: |--app | |--job.ts |--api | |--R.d.ts |--tests | |--job.test.ts ...

The type 'elementfinder' cannot be assigned to a parameter of type 'boolean'

Currently, I am working on a function that checks if a checkbox is selected. If it's not checked, then the function should click on it. However, I encountered an error message stating "argument of type 'elementfinder' is not assignable to pa ...

Angular 4: Utilizing reactive forms for dynamic addition and removal of elements in a string array

I am looking for a way to modify a reactive form so that it can add and delete fields to a string array dynamically. Currently, I am using a FormArray but it adds the new items as objects rather than just simple strings in the array. Here is an example of ...

Tips for calculating the total count of a specific field within a JSON array with TypeScript

I have a JSON array. "user": { "value": [ { "customerNo": "1234" }, { "customerNo": "abcd" }, { "c ...

Sorting through a JavaScript array

I am facing a peculiar problem while trying to filter an array in TypeScript. Here is the structure of my object: Sigma.model.ts export class Sigma { sigmaId: number; name: string; userId: number; starId: string; } `` The starId property contains com ...

Material-UI React Native components: Injecting Styles without Props

import {createStyles, WithStyles} from "@material-ui/core"; const styles = (theme: Theme) => createStyles({ root: {} }); interface MyProps extends WithStyles<typeof styles> { } export class MyComponent extends Component<MyProps ...

Creating a custom hook to detect when multiple elements are hovered over

I am currently working on creating a hook that can identify when hover is triggered over specific buttons. Here is what I have so far: enum options { buttonOne: 'buttonOne', buttonTwo: 'buttonTwo' } type HoverType= { [key in opti ...

How can RootStateOrAny be turned off in React with typescript?

Whenever I need to employ useSelector, I find myself repeating this pattern: const isLoading = useSelector( (state) => state.utils.isLoading ); Is there a shortcut to avoid typing out RootStateOrAny each time? It's starting to become a hassl ...

Ways to effectively implement a function type specified in an interface

Consider the following interface: interface MyProps { onEvent: (name: string, data: any) => void; } Is there a way to utilize the function type in order to avoid unused parameter errors during compilation? eventHandler = (name: string, data: any) = ...

Is there a way for me to connect to my Firebase Realtime Database using my Firebase Cloud Function?

My current challenge involves retrieving the list of users in my database when a specific field is updated. I aim to modify the scores of players based on the structure outlined below: The Realtime Database Schema: { "users": { &quo ...

Using both withNextIntl and withPlaiceholder simultaneously in a NextJS project causes compatibility issues

I recently upgraded to NextJS 14 and encountered an issue when deploying my project on Vercel. The next.config.mjs file in which I wrapped my nextConfig in two plugins seemed to prevent the build from completing successfully. As a workaround, I decided t ...

Lack of code completion in Nuxt options API when using typescript

After setting up Nuxtjs with typescript, I noticed that there are no code completions in the template and script as expected based on the title. Here is the code: <script lang="ts"> import Vue from 'vue'; import { FeaturedJobs } ...

Using GraphQL in React to access a specific field

Here is the code snippet I am working with: interface MutationProps { username: string; Mutation: any; } export const UseCustomMutation: React.FC<MutationProps> | any = (username: any, Mutation: DocumentNode ) => { const [functi ...

Tips for creating an operation within a JSON document?

Today, I am attempting to customize the appearance of my audiobook list. However, when trying to add an aspectRatio key-value pair to each object in my JSON file, I encountered an error. https://i.stack.imgur.com/Qb3TX.png https://i.stack.imgur.com/qTkmx. ...

Handle and manage errors within the controller in Express.js to prevent the further execution of asynchronous functions

Consider a scenario where there is an API endpoint /register, designed to register new users in an application. The function utilized is asynchronous, as an attempt is made to incorporate an asynchronous process within an AuthController when performing pas ...

Alerting Users Before Navigating Away from an Angular Page

I am looking to implement a feature in my app that will display a warning message when attempting to close the tab, exit the page, or reload it. However, I am facing an issue where the warning message is displayed but the page still exits before I can resp ...

Error message: "The toJSON method is not found for the item in the nested array of

Encountering an issue with NSwag in my Angular project where it throws an error when attempting to send data if the object contains a nested array of objects like this: export interface IJobAdDto { mainJobAd: JobAddDetailsDto; differentLanguageJobA ...