Leveraging keyof and Pick from a single source list for type definitions

In order to streamline the process, I want to define the necessary properties in a single list[], and then use that as the template for both types I am utilizing. Currently, I have to manually input them in two separate locations.

By employing keyof, I can ensure that I am only choosing from available props

type DealPropertiesKeys = keyof DealProperties

This enables me to specify which properties need to be retrieved from the API

  const deal = await hubSpotClient.crm.deals.basicApi.getById(dealId, [
    'dealname',
    'loan_type',
    'asset_type',
    'a_c_square_footage',
    'borrowing_entity_type',
    'borrowing_entity',
    'date_of_formation',
    'estimated_value',
    'exit_strategy',
    'fixed_or_arm',
    'intended_use',
    'lender',
    'loan_channel',
    'loan_program',
    'ltv',
    'project_name',
    'property_address',
    'property_type',
    'requested_terms',
    'subject_property_address',
    'subject_property_city',
    'subject_property_state',
    'subject_property_zip_code',
    'year_built',
    'amount',
    'hubspot_owner_id',
    'outstanding_mortgage_balance',
  ] as DealPropertiesKeys[])

When working with the returned object, I aim to type it according to the selected properties on the request.

type DealProps = Pick<
  DealProperties,
  | 'dealname'
  | 'loan_type'
  | 'asset_type'
  | 'a_c_square_footage'
  | 'borrowing_entity_type'
  | 'borrowing_entity'
  | 'date_of_formation'
  | 'estimated_value'
  | 'exit_strategy'
  | 'fixed_or_arm'
  | 'intended_use'
  | 'lender'
  | 'loan_channel'
  | 'loan_program'
  | 'ltv'
  | 'project_name'
  | 'property_address'
  | 'property_type'
  | 'requested_terms'
  | 'subject_property_address'
  | 'subject_property_city'
  | 'subject_property_state'
  | 'subject_property_zip_code'
  | 'year_built'
  | 'amount'
  | 'hubspot_owner_id'
  | 'outstanding_mortgage_balance'
>

Answer №1

This code snippet demonstrates a clever approach to working with arrays in TypeScript. By first defining the array as a constant and then using typeof theArray[number], all elements of the array are obtained as a union type. Additionally, since the properties of the const array will be passed to the getById function, it's important to declare the parameter as readonly (as indicated by the comments in the code).

type DealPropertiesKeys = keyof DealProperties

const requestDealProperties = [
  'dealname',
  'loan_type',
  ...
] as const                          // <- Defined as const here

// v Obtaining union type - `typeof theArray[number]`
type RequestDealProperties = typeof requestDealProperties[number]

type DealProps = Pick<
  DealProperties,
  RequestDealProperties            // <- Using union type here
>

// Dummy DealProperties placeholder - providing type declaration for keys
interface DealProperties {
  dealname: string
  loan_type: string
  asset_type: string
  ...
}

// Testing the getById function
function getById(
  dealId: string,
  properties: readonly DealPropertiesKeys[],  // <- Declaring as readonly array
) {
  console.log(dealId, properties)
}

getById('1234', requestDealProperties)

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

Error: Module './App' not found in webpack module

I am encountering the error Uncaught Error: Module not found: Can't resolve ./App' and ./store in client/src. in the console of my local environment when I execute npm start from the client directory. The console is showing 2 errors: ERROR in ...

Errors during TypeScript compilation in Twilio Functions

When I run npx tsc, I encounter the following errors: node_modules/@twilio-labs/serverless-runtime-types/types.d.ts:5:10 - error TS2305: Module '"twilio/lib/rest/Twilio"' does not export 'TwilioClientOptions'. 5 import { Twil ...

Experiencing difficulties while trying to showcase a PDF within the Expo Go app

I am currently developing a React Native application that requires the display of PDF files. I have tried two different methods, one using react-native-webview and the other with react-native-pdf, but both approaches are presenting challenges. This is how ...

Using the useContext hook in a TypeScript class component: a step-by-step guide

I am working with a TypeScript class component and have successfully created a context that can be accessed globally. I am interested in learning how to implement this context in a .ts class component and if it is possible to use it in a pure TypeScript ...

Is it possible to include a conditional type in TypeScript using inlining?

Apologies if this question seems basic to those well-versed in typesystems. I'm puzzled by the difference in outcomes when inlining a conditional statement in TypeScript. For instance, using the Extract conditional leads to different results dependin ...

What techniques can be used to determine which exact key was matched by a generic?

I am trying to find a method to deduce a more general string type key from a specific string that can be associated with it. type Foo = { [x: `/tea/${string}/cup`]: void; [x: `/coffee/${string}/time`]: void; [x: `/cake/${string}/tin`]: void; } type ...

Enable child classes to overwrite using either a function attribute or a method

class Foo { foo: () => void } class Bar extends Foo { foo() {} } Is there a way in which TypeScript can be configured to allow the scenario described above? Playground The 'Foo' class defines a property 'foo' as an instance ...

Utilizing the polymer paper-dialog component in an Angular 2 TypeScript application

I have imported the paper-dialog from bower, but I am facing an issue with showing the dialog using the open() method. app.component.html <paper-icon-button icon="social:person-outline" data-dialog="dialog" id="sing_in_dialog" (click)="clickHandler()" ...

Is it necessary to manually unsubscribe from observables in the main Angular component?

I'm facing a dilemma with my Observable in the root Angular (6.x) component, AppComponent. Typically, I would unsubscribe from any open Subscription when calling destroy() using the lifecycle hook, ngOnDestroy. However, since the AppComponent serv ...

Tips for effectively utilizing the Angular ngIf directive for toggling the visibility of elements

<div *ngFor = "let element of myElements, let i=index" [ngClass]="{'selected':element[i] == i}"> <li> Name: {{element.element.name}}</li> <li> Description: {{element.element.description}}</li ...

When the boolean is initially set to false, it will return true in an if statement without using

My Angular component contains a component-level boolean variable and an onClick event. Here's what the HTML file looks like: <div class="divClass" (click)="onClick($event)"></div> The relevant code from the TypeScript file is as follows: ...

Tips for waiting for an observable loop

When using my application, the process involves uploading a series of images in order to retrieve the file IDs from the system. Once these IDs are obtained, the object can then be uploaded. async uploadFiles(token: string):Promise<number[]> { let ...

Incorporating Imported Modules into the Final Build of a Typescript Project

In my Visual Studio Code Typescript project, I have set up some basic configurations and used npm to download libraries. One of the main files in my project is main.ts which includes the following code: import ApexCharts from 'apexcharts' var c ...

A guide on implementing Redux Toolkit in an SPFX (typescript) project

I am currently working on developing SPFX components using typescript and webpack. My goal is to integrate redux toolkit into my project, but it is causing compilation errors. Here is what I have done so far: Created the project structure using yo Insta ...

Unveiling the secrets of the Google Region Lookup API

I am struggling to incorporate the Region Area Lookup feature from Google Maps into my project. Despite it being an experimental feature, I am having difficulty getting it to function correctly. Initially, I attempted to integrate this feature into a Reac ...

Ditch the if-else ladder approach and instead, opt for implementing a strategic design

I am currently working on implementing a strategic design pattern. Here is a simple if-else ladder that I have: if(dataKeyinresponse === 'year') { bsd = new Date(moment(new Date(item['key'])).startOf('year&apos ...

Issue with TypeChecking in Angular4's HttpClient

I have been reading about how the new Angular's HttpClient can perform TypeChecking. Based on that information, I have written the following code: post(path: string, body: Object = {}): Observable<ValorTest> { return this.http.post<ValorTest ...

Is there a way to loop through objects in Angular 2

I am working with an Array of Objects named comments, and my goal is to select only the ones that have a specific post id and copy them to another array of objects. The issue I am facing is finding a way to duplicate the object once it has been identified. ...

Is it possible to indicate the base type for a generic function?

Is it possible to define the generic type T as an Object rather than a primitive type like number or string? For example, this clone function should only accept Objects as input. It will destructure the input object o, set its prototype back to that of th ...

Error message: "Incompatible types in Typescript"

As I delve into learning TypeScript, I have encountered two errors that are causing me some trouble. We have a problem with the following lines of code: Type 'string | null | undefined' is not assignable to type 'string | RegExp | QuerySelec ...