Using the Typescript type 'never' for object fields: a guide to implementing it

I'm attempting to make this specific example function similar to this one:

interface Foo {
    a: number;
    b: string;
    c: boolean;
}

type Explode<T> = keyof T extends infer K
    ? K extends unknown
    ? { [I in keyof T]: I extends K ? T[I] : never }
    : never
    : never;


type Test = Explode<Foo>;

const test: Test = {a: 1};

This results in the error:

Type '{ a: number; }' is not assignable to type '{ a: number; b: never; c: never; } | { a: never; b: string; c: never; } | { a: never; b: never; c: boolean; }'.
  Type '{ a: number; }' is missing the following properties from type '{ a: number; b: never; c: never; }': b, c

Is there a way to create an object of type Test without encountering the error? I am looking for a type that can accommodate either the field a, b, or c (or be an empty object {}).

Answer №1

I stumbled upon the solution. In order to resolve the issue, I had to adjust the fields of Foo to be optional in the following way:

UPDATED to incorporate the recommendation by @apokryfos

interface Foo {
    a: number;
    b: string;
    c: boolean;
}

Now I am able to:

interface Foo {
    a: number;
    b: string;
    c: boolean;
}

type AtMostOneOf<T> = keyof T extends infer K
    ? K extends unknown
    ? { [I in keyof T]+?: I extends K ? T[I] : never }
    : never
    : never;


type Test = AtMostOneOf<Foo>;

const test: Test = {a: 1}; // permitted
const test1: Test = {b: 'asd'}; // permitted
const test2: Test = {a: 1, b: 'asd'}; // not permitted
const test3: Test = {} // permitted

Playground

Answer №2

To create the Explode type, you can do the following:


type Explode<T> = {
    [K in keyof T]: {
        [key in K]: T[K]
    }
}[keyof T]

After defining the Explode type, the type Test will be structured like this:

type Test = {
    a: number;
} | {
    b: string;
} | {
    c: boolean;
}

Check out this TS Playground for more information.

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

Incorrect date format sent to backend through API

Within my Angular + Angular Material application, I am facing an issue with a date range picker. My goal is to send the selected start and end dates in a formatted manner through an API call. However, when the date values are sent over the API as part of t ...

Forwarding from a user interface element in Next.JS

I am currently working on a project utilizing Next.js 13, and I have encountered a situation where I need to invoke a client-side component from a server-side page. The specific component in question is the DeleteAddressAlertDialog which interacts with my ...

Displaying a child component as a standalone page rather than integrating it within the parent component's body

I'm currently working on implementing nested navigation in my website, but I am facing challenges with loading the child component without the need to include a router-outlet in the parent component. This setup is causing the child component's co ...

Experiencing constant errors with axios requests in my MERN Stack project using a Typescript Webpack setup

Hey there, I'm in need of some help! I've been working on a MERN Stack project and have set up Webpack and Babel from scratch on the frontend. However, every time I send a request to my Node Server, I keep getting an error message back. Can anyon ...

What is the best way to obtain clear HTTP request data in a component?

My service retrieves JSON data from the backend: constructor(private http: Http) { }; getUsers(): Observable<any> { return this.http.get('http://127.0.0.1:8000/app_todo2/users_list'); }; In the component, this data is processed: ng ...

Understanding the Use of Promises and Async/Await in Typescript

Struggling with asynchronous libraries in Typescript, I find myself looking for a way to wait for promises to be resolved without turning every method into an async function. Rather than transforming my entire object model into a chain of Promises and asyn ...

Exploring TypeScript and React Hooks for managing state and handling events

What are the different types of React.js's state and events? In the code snippet provided, I am currently using type: any as a workaround, but it feels like a hack. How can I properly define the types for them? When defining my custom hooks: If I u ...

Show the user's chosen name in place of their actual identity during a chat

I'm facing an issue where I want to show the user's friendly name in a conversation, but it looks like the Message resource only returns the identity string as the message author. I attempted to retrieve the conversation participants, generate a ...

Unable to execute the Vite project

I ran into an issue with my Vite project yesterday. I closed it and now that I have reopened it, the 'npm run dev' command is throwing an error. My project is built using Vite with React and TypeScript. Attached is a screenshot of the error mess ...

Achieving the highest ranking for Kendo chart series item labels

Currently, I am working with a Kendo column chart that has multiple series per category. My goal is to position Kendo chart series item labels on top regardless of their value. By default, these labels are placed at the end of each chart item, appearing o ...

Encountering issues when trying to import const enums in a webpack project using babel

Currently, I am working on a react project that was initially created using create-react-app. However, we later ejected and made extensive modifications to the webpack configuration. My current struggle lies in importing const enums from external libraries ...

What is the best way to create a generic function parameter for a single property of an object?

I am trying to refactor a generic function into accepting parameters as a single object function test<T>(a: string, b: T, c: number) Instead, I want the function to receive an object like this: function test(params: {a: string; b: T, c: number}) I ...

Mocking a service dependency in Angular using Jest and Spectator during testing of a different

I am currently using: Angular CLI: 10.2.3 Node: 12.22.1 Everything is working fine with the project build and execution. I am now focusing on adding tests using Jest and Spectator. Specifically, I'm attempting to test a basic service where I can mo ...

An error occurred while defining props due to a parsing issue with the prop type. The unexpected token was encountered. Perhaps you meant to use `{`}` or `}`?

const dataProps = defineProps({ selectedData: <Record<string, string>> }); Under the closing bracket, there is a red line indicating: Error: Unexpected token. Consider using {'}'} or &rbrace; instead?eslint Expression expecte ...

Issue with updating state in child component preventing addition to state

Recently, I made the switch to TypeScript in my NextJS project using Create T3 App. One of the components in my app involves updating the state after a Prisma mutation is performed. I attempted to pass the setItems (which was initialized with useState) to ...

When delving into an object to filter it in Angular 11, results may vary as sometimes it functions correctly while other times

Currently, I am working on implementing a friend logic within my codebase. For instance, two users should be able to become friends with each other. User 1 sends a friend request to User 2 and once accepted, User 2 is notified that someone has added them a ...

Is it possible to confirm that a value is a valid key without prior knowledge of the object's keys during compile-time?

Is there a way in TypeScript to declare that a variable is a keyof some Record without prior knowledge of the keys? For instance, consider an API response returning JSON data. Is it possible to define a type for the keys of this payload to ensure that whe ...

The error message "Property is not found on type 'Object'" suggests that the property being accessed does not

I wrote a function called getAll getAll<T>() { return this.http.get(`${environment.apiUrl}/products`); } Here is how I am invoking it: this.productService.getAll() .pipe(first()) .subscribe(products => { debugger let s ...

Mastering the art of calculating month differences on TypeScript dates in an Angular environment

Currently, I am working with Angular 7. Suppose I have a fixed rate X, for example, an amount I need to pay each month. Now, if I have two specified dates startDate and endDate, I want to calculate the total payment due for this given time period. To prov ...

Reasons behind Angular HttpClient sorting JSON fields

Recently, I encountered a small issue with HttpClient when trying to retrieve data from my API: constructor(private http: HttpClient) {} ngOnInit(): void { this.http.get("http://localhost:8080/api/test/test?status=None").subscribe((data)=> ...