Select and compress a type declaration in TypeScript

Exploring the functionalities provided in the standard library, I came across some interesting ones and decided to experiment. Can TypeScript handle something like this?

interface BrandNewType {
    X: { x1 : string }
    Y: { y1 : number, y2: boolean }
    Z: {}
    W: {z: string}
}


const result : {x1: string, y1: string, y2: string} = selectAndMerge<BrandNewType>(['X', 'Y'])

Answer №1

To achieve this, we can create an intersection by combining the selected property types.

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type PickAndFlatten<T, K extends keyof T> = UnionToIntersection<T[K]>;

The UnionToIntersection function was shared by @jcalz in this thread. You can find a detailed explanation there and make sure to show appreciation with an upvote :) Using T[K] helps us retrieve the type of the specified key K. If K consists of multiple keys in a union, T[K] will be a union of all the corresponding property types.

In order to implement this in a function, we require two type parameters – one for the type we are selecting from and another for the keys being picked.

interface OriginalType {
  A: { a: string };
  B: { b1: string, b2: number };
  C: {};
  D: { c: string };
}

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type PickAndFlatten<T, K extends keyof T> = UnionToIntersection<T[K]>;

function pickAndFlatten<T, K extends keyof T>(o: T, keys: K[]): PickAndFlatten<T, K> {
  // Implementation not tested
  const entries = Object.entries(o)
      .filter(([k, v]) => keys.includes(k as K))
      .map(([k, v]) => v);

  return Object.assign({}, entries) as any;
}

let o: OriginalType;
const r = pickAndFlatten(o, ['A', 'B']); // { a: string; } & { b1: string; b2: number; }

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

What is the proper way to type the SubmitEvent so that the event.target.children property can be accessed

Below is the form I currently have: <form id="search" method="post"> <input type="text" name="query" id="search-field"/> </form> I am looking to add a submit event listener in TypeScript: ...

Incorporate MUX Player (Video) into Angular versions 14 or 15

Mux offers a video API service with its own player: MUX Player I am interested in integrating this npm package specifically into a component in Angular 14/15. The JavaScript should only be loaded when this particular component is rendered. Integration Th ...

Vite in Vue 3 does not stop build process for errors

Encountered the error message "TS2322: Type 'number' is not assignable to type 'string'." Instead of fixing it in the code, I prefer to disable it. Using "vue-tsc --noEmit && vite build" for my build in package.json. Currently workin ...

Utilizing a syntax highlighter in combination with tsx React markdown allows for cleaner

I'm currently looking at the React Markdown library on Github and attempting to incorporate SyntaxHighlighter into my markdown code snippets. When I try to implement the example code within a function used for rendering posts, I encounter the error de ...

Version 1.9.3 of Redux Toolkit is encountering an error stating that the 'push' property is not found on the type 'WritableDraft<CartState>'

Currently delving into Redux Toolkit using TypeScript and facing a roadblock that seems deceptively simple. Unfortunately, my current knowledge isn't enough to unravel this puzzle and I'm in need of some guidance. The issue arises with an error ...

Having trouble retrieving the user-object within tRPC createContext using express

I'm encountering an issue with my tRPC configuration where it is unable to access the express session on the request object. Currently, I am implementing passport.js with Google and Facebook providers. Whenever I make a request to a regular HTTP rout ...

Working with TypeScript to set a value for an object's field

I have two objects of the same model: interface Project { _id?: string title: string description: string goal: string tasks?: Task[] createdAt?: Date updatedAt?: Date } The first object contains all fields from the interface, while the secon ...

What is the method for inserting an object into a jsonArray in TypeScript?

I am trying to add an object to existing JSON data in TypeScript. I am new to TypeScript and have created an array variable called jsonArrayObject, which contains a boolean[] type. This jsonArrayObject holds a contactModel object with properties like fname ...

The timezone plugin in day.js may sometimes generate an incorrect date

For a while, I've been using dayjs in my angular project to convert timestamps from UTC to localtime. However, after my recent update, this functionality stopped working. This isn't the first issue I've encountered with dayjs, so I decided t ...

What is the equivalent of html script tags in Webpack 2?

I recently downloaded a new npm module that suggests including the following code in my project: <link href="node_modules/ng2-toastr/bundles/ng2-toastr.min.css" rel="stylesheet" /> <script src="node_modules/ng2-toastr/bundles/ng2-toastr.min.js"&g ...

NPM: There are no valid TypeScript file rules specified

Currently working on a small project using React.JS. Whenever I execute : npm run start, the following message gets logged: Starting type checking and linting service... Using 1 worker with 2048MB memory limit Watching: /Users/John/Projects/myProject/src ...

What is the best way to display various tables depending on the grouping of a specific row value?

Recently, I came across some interesting JSON data that looks like this: [ { "fruit":"apple", "country": "A" }, { "fruit":"banana", "country": "b" }, { "fruit":&q ...

What is the most effective way to condense these if statements?

I've been working on a project that includes some if statements in the code. I was advised to make it more concise and efficient by doing it all in one line. While my current method is functional, I need to refactor it for approval. Can you assist me ...

Conceal object from inventory upon clicking

As someone who is new to React and Typescript, I am facing challenges in understanding how to hide a ticket from the list when the hide button is clicked. displayTickets = (tickets: Ticket[]) => { const filteredTickets = tickets.filter(t => ...

Angular is not able to access the value of a promise in a different function after it has been retrieved

I have a form with default values that should be added to the form fields when it appears. There are two functions: #1 for fetching data from the backend and #2 for displaying the form: person$: any; ngOnInit() { this.getPersonData(123) this.buildPer ...

What is the best way to connect to a library using a script within a Typescript React application?

I'm a newbie to React and haven't worked on web development in years, so I'm facing a basic issue: Currently, I'm working on implementing a Stripe-based payment flow in a React web app (written in Typescript) and I've hit a roadbl ...

Trying to find a more efficient method to export multiple classes as an array in typescript

I've organized my files like this: index.ts folder/ a.ts b.ts subfolder/ c.ts d.ts e.ts ... In each file, there is one default exported class and I want index.ts to export all these classes as an array. Currently, I achieve thi ...

Which symbol or character corresponds to the public "get symbol" method?

While going through some Typescript code, I came across a line that is giving me trouble to understand. const symbol = Symbol.for('symbolname'); class Something { public get [symbol]() { return true; } ... } I am confused abou ...

Revise the classification of an instance variable within a subclass

I am pondering about the topic of inheritance and types for instance variables in typescript. Consider a basic class as shown below: class Person { instanceVariable: Object; age: Number; constructor(instanceVariable: Object, age: Number) { this ...

Component test in React with TypeScript has resulted in failure

I keep encountering failures whenever I run the test. It's frustrating not knowing where I am going wrong. Does anyone have advice on how to effectively test those if statements and the child component? Currently, I'm utilizing jest and enzyme f ...