Tips for retrieving keys of a specific type from an object

If I were to create an interface named Data:

interface Data {
  key1: number
  key2: boolean
  set1: SomeInterface[]
  set2: AnotherInterface[]
}

Is there a way to retrieve the properties of the interface Data that includes [] in the form of a discriminated union type?

Expected result for the given Data interface shown above:

// "set1" | "set2"

Answer №1

To achieve this, you can leverage the power of mapped types:

type SomeInterface = { tag: 'SomeInterface' }
type SomeOtherInterface = { tag: 'SomeOtherInterface' }

interface Obj {
    string1: string
    string2: string
    array1: SomeInterface[]
    array2: SomeOtherInterface[]
}

type ObtainKeys<Obj, Type> = {
    [Prop in keyof Obj]: Obj[Prop] extends Type ? Prop : never
}[keyof Obj]

type GetArrayKeys = ObtainKeys<Obj, Array<any>> // "array1" | "array2"

type GetStringKeys = ObtainKeys<Obj, string> //  "string1" | "string2"

Interactive Example

ObtainKeys is a versatile function that takes two arguments. The first argument is the object to check, and the second argument is the type to extract.

The line:

[Prop in keyof Obj]: Obj[Prop] extends Type ? Prop : never
loops through all keys of the Obj and evaluates if Obj[Prop] matches the specified type. If it does, return Prop; otherwise, return never.

Utilizing [keyof Obj] allows us to consolidate all values of our iterated type, as the desired Prop resides in the value position. The union operation with never ensures we retain the original type without unwanted never values.

Answer №2

Another method worth considering is using this syntax for a similar purpose:

type ExtractKeys<T, V> = keyof {
  [K in keyof T as T[K] extends V ? K : never]: any
}

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 validator is incorrectly diagnosing the input as 'invalid' when in reality it is not

Currently, I am working on creating a text field that must not be empty and should also not start with a specific set of characters (let's say 'test'). For example, I want testxyz or an empty field to be considered invalid, while anything e ...

What is the method for choosing an element by class name in TypeScript?

Currently, I'm working on creating a responsive menu bar that collapses on smaller screens. The challenge I'm facing is that I'm using TypeScript for this project. Is there any guidance on how to translate the following code into TypeScript? ...

The browser is throwing errors because TypeScript is attempting to convert imports to requires during compilation

A dilemma I encountered: <script src="./Snake.js" type="text/javascript"></script> was added to my HTML file. I have a file named Snake.ts which I am compiling to JS using the below configuration: {target: "es6", module: "commonjs"} Howeve ...

How to stop a checkbox from being selected in Angular 2

I have a table with checkboxes in each row. The table header contains a Check All checkbox that can toggle all the checkboxes in the table rows. I want to implement a feature where, if the number of checkboxes exceeds a certain limit, an error message is ...

ESLint refuses to be turned off for a particular file

I am in the process of creating a Notes.ts file specifically for TypeScript notes. I require syntax highlighting but do not want to use eslint. How can I prevent eslint from running on my notes file? Directory Structure root/.eslintignore root/NestJS.ts r ...

The specified file cannot be found within the Node file system

I am working on a project that involves reading a file using Node fs, and I have the following code: const files: FileSystemTree = { "Component.tsx": { file: { contents: fs.readFileSync( `../../apps/components ...

Tips for implementing Peer.js in Next.js using TypeScript?

Next.js has the ability to run on the server side, which can result in Peer.js throwing errors when used with Next.js. One user on Stack Overflow explains this issue: The error is likely due to peer js performing side effects during import. The suggest ...

"Retrieve objects from an array based on specified minimum and maximum values, while also checking for any null

My current dataset is structured as follows: const data = [ { id: '11se23-213', name: 'Data1', points: [ { x: 5, y: 1.1 }, { x: 6, y: 2.1 }, { x: 7, y: 3.1 }, { x: 8, y: 1.5 }, { x: 9, y: 2.9 ...

Creating Swagger documentation for dynamic request and response is a process that involves documenting the various

Our API application operates dynamically using SQL-defined metadata to generate reports based on the requests it receives. When a JSON request is passed in like the examples below: { "Field1": "Value1" "GroupBy": [&qu ...

Generics-based conditional type that verifies entry properties

I developed a function that accepts an argument with two different architectures. I intentionally avoided enforcing rules to allow flexibility for the user, which is now causing me some headaches ...

How can we leverage Shared and Core modules alongside Feature modules in Angular development?

When developing my Angular application, I have adopted a specific architecture approach and included a shared.module.ts file in the shared folder. While leveraging lazy-loading in my app, I find myself puzzled about the necessary imports, declarations, and ...

What is the best way to add an external .js file to my Angular 2 application?

I'm currently working on a project using Angular 2's TypeScript API along with webpack to develop a web application. However, I've encountered an issue where one of my components needs to utilize functions from an external .js file that is p ...

Developing a constrained variable limited to specific values

Recently delving into Typescript - I am interested in creating a variable type that is restricted to specific values. For instance, I have an element where I want to adjust the width based on a "zoom" variable. I would like to define a variable type call ...

Utilizing Angular Validators.email with the ability to accept null values

In my .ts file, I have an Angular validator set up like this: this.detailsForm = formBuilder.group( { email: ['', Validators.compose([Validators.email])] }); While this setup works fine, the email validator also applies the required validat ...

"Exploring Angular 9: A guide to retrieving form data with an array of objects [Revised as of July 29th, 2020

I am encountering an issue with my Angular 9 form code. I am getting the error "ERROR TypeError: Cannot read property 'mobile_number' of undefined" and I need help in resolving this problem. <form (ngSubmit)="processForm()"> & ...

Unable to transfer props object to React component using TypeScript

Apologies if this seems like a basic issue, but I've been struggling with it for the past two days. I'm currently working on writing a simple unit test in Vitest that involves rendering a component to the screen and then using screen.debug(). The ...

Running Jest tests concurrently causes a TypeError due to converting a circular structure to JSON

While running Jest Tests in parallel, I encountered the following error. Interestingly, when running each test individually or using --RunInBand, they all pass without any issues. Test suite failed to run Jest worker encountered 4 child process except ...

The type 'typeof globalThis' does not have an index signature, therefore the element is implicitly of type 'any'. Error code: ts(7017) in TypeScript

I'm encountering an issue with my input handleChange function. Specifically, I am receiving the following error message: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.ts(7017) when att ...

What is the process for importing a TypeScript module in the StackBlitz editor?

When I enter the editor at Stackblitz.com and start a new Angular project, it comes with default files and folders already set up. In the "Dependencies" section, I decide to add shortid. So, I input that in the designated box and it begins loading the cor ...

Error in Typescript persists even after short-circuit evaluation is used

Kindly review the provided code sample type type1 = string[] | undefined; let variable1 : type1 = undefined; console.log(variable1 && variable1.length); Upon attempting to run this code in Typescript Playground, an error is generated stating Pro ...