Obtain data based on the type of property

When examining the provided code snippet, I aim to filter properties based on their data type:

interface Wrapper<T> {
    x: T;
}

interface WrapperOpt<T> {
    y?: T;
}

interface A {
    a1: number;
    a2: Wrapper<number>;
    a3: WrapperOpt<number>;

    b1?: string;
    b2?: Wrapper<string>;
    b3?: WrapperOpt<string>;
}

type Wrapped = { [key in keyof A]: A[key] extends Wrapper<infer T> ? T : never };
type WrappedOpt = { [key in keyof A]: A[key] extends WrapperOpt<infer T> ? T : never };

This setup effectively filters by the Wrapper type, resulting in Wrapped where a2 and b2 are not never:

type Wrapped = {
    a1: never;
    a2: number;
    a3: never;
    b1?: never;
    b2?: string;
    b3?: never;
}

However, the same process encounters issues with the WrapperOpt type, leading to the creation of WrappedOpt with unexpected data types for a3 and

b3</code:</p>

<pre><code>type WrappedOpt = {
    a1: {};
    a2: {};
    a3: {};
    b1?: {};
    b2?: {};
    b3?: {};
}

The desired outcome is to have a3 and

b3</code exhibit the correct types while others are designated as <code>never
:

type Wrapped = {
    a1: never;
    a2: never;
    a3: number;
    b1?: never;
    b2?: never;
    b3?: string;
}

What steps can be taken to address this discrepancy?

Furthermore, future plans involve eliminating the never entries in types, as outlined in this resource, to achieve a more streamlined approach:

type Wrapped = {
    a2: number;
    b2?: string;
}

type WrappedOpt = {
    a3: number;
    b3?: string;
}

Answer №1

Here's the solution I discovered: make sure to wrap the left type when checking the extends condition with Required:

type WrappedOpt = { [key in keyof A]: Required<A[key]> extends WrapperOpt<infer T> ? T : never };

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

Utilize a function to wrap the setup and teardown code in Jest

I am attempting to streamline some common setup and teardown code within a function as shown below: export function testWithModalLifecycle() { beforeEach(() => { const modalRootDom = document.createElement('div') modalRootDom.id = M ...

The functionality of `import { Dialogs } from "@nativescript/core"; seems to be malfunctioning

For my project, I am in need of using Dialogs. Unfortunately, the import from @nativescript/core as mentioned in their documentation is not working. I keep encountering this error: Module '"@nativescript/core"' has no exported member &a ...

Angular 13's APP_INITIALIZER doesn't wait as expected

Recently, I have been in the process of upgrading from okta/okta-angular version 3.x to 5.x and encountered an unexpected bug. Upon startup of the application, we utilized APP_INITIALIZER to trigger appInitializerFactory(configService: ConfigService), whi ...

TypeScript encountered an unexpected { token, causing a SyntaxError

Despite multiple attempts, I can't seem to successfully run my program using the command "node main.js" as it keeps showing the error message "SyntaxError: Unexpected token {" D:\Visual Studio Code Projects\ts-hello>node main.js D:&bsol ...

Utilizing Angular 2's NgFor directive in SVG Elements

I want to use ngFor to draw an SVG Element that consists of lines. I am struggling with the implementation and need some help fixing the code. Here is what I have so far: my-component.js: import {Component} from 'angular2/core'; @Component({ ...

What is the method to group a TypeScript array based on a key from an object within the array?

I am dealing with an array called products that requires grouping based on the Product._shop_id. export class Product { _id: string; _shop_id: string; } export class Variant { variant_id: string; } export interface ShoppingCart { Variant: ...

The parseFloat function only considers numbers before the decimal point and disregards

I need my function to properly format a number or string into a decimal number with X amount of digits after the decimal point. The issue I'm facing is that when I pass 3.0004 to my function, it returns 3. After reviewing the documentation, I realized ...

How can I utilize identical cucumber steps for both mobile and web tests while evaluating the same functionality?

In order to test our website and React Native mobile app, we have developed a hybrid framework using webdriver.io and cucumber.io. We currently maintain separate feature files for the same functionality on both the web and mobile platforms. For example, i ...

Replacing a push operation in JavaScript with a splice operation

Upon entering a screen, 5 promises are automatically loaded using promise.all. The issue is that they are executed in a random order, and within each function, I use a push to store the information. The problem arises when I need to change the push to a s ...

A step-by-step guide on reading/loading a JSON file using Typescript

I'm fairly new to Typescript and I'm attempting to parse a simple JSON file using Typescript. After searching online and testing different solutions, I still haven't been able to find a straightforward code snippet that reads a local JSON fi ...

What causes TypeScript's ReadonlyArrays to become mutable once they are transpiled to JavaScript?

Currently, I am in the process of learning Typescript by referring to the resources provided in the official documentation. Specifically, while going through the Interfaces section, I came across the following statement: TypeScript includes a special t ...

Elements constrained by themselves in a rest parameter with generic types

When using Typescript, it is possible to infer tuple types for generic rest parameters that are constrained by an array type. However, in my specific case, this functionality does not seem to work as expected. I am attempting to pass a series of pairs co ...

Is it possible to iterate over an enum using Object.entries<T>(Enum).map() in TypeScript, or does it only function with string-based enums?

Currently, I am in the process of developing a react form that requires users to select options related to a job. These options are represented by enums, with some being string-based and others number-based. For instance, here is an example of a string-ba ...

WebStorm's TypeScript definitions are failing to function properly

I'm experiencing an issue with my three.js code and TypeScript definitions in settings. Despite enabling them, there doesn't seem to be any effect. I've downloaded everything and checked the necessary boxes, but nothing is changing. WebStorm ...

Verify whether the mat-dialog is currently displayed

Purpose: To trigger a dialog on page load only if it hasn't already been opened. The dialog component is separate from the current page. Issue: The dialog is opening twice. I attempted to troubleshoot by referencing StackOverflow articles like Angul ...

Tips for pulling out specific keys from a typed object using an index signature

TL;DR Query: How do I create a type converter in TypeScript that extracts the defined keys from objects typed with index signatures? I am looking to develop a type "converter" in TypeScript that takes a type A as input and outputs a new type B with keys ...

Is there a way to change a .pptx document into a base64 string?

Currently, I am working on a project that involves creating an addin for Office. The challenge I am facing is opening other pptx files from within the addin. After some research, I discovered that I need to use base64 for the PowerPoint.createPresentation( ...

Utilizing a method from a separate class in Ionic 2

Having trouble using the takePicture() function from camera.ts in my home.ts. I keep getting an error message saying "No provider for CameraPage!" Any assistance on how to resolve this issue would be greatly appreciated, as I am new to this language and ju ...

React TypeScript - Module not found

Organizational structure: src - components - About.tsx In an attempt to optimize performance, I am experimenting with lazy loading: const About = React.lazy(() => import('components/About')); However, Visual Studio Code is flagging &ap ...

Conflicting Angular controller names within different modules

I'm facing an issue where two modules (A and B) with controllers of the same name are conflicting when imported into module C. Is there a recommended solution to prevent this conflict, such as using a naming convention like "module.controller" for ea ...