Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

114
Views
How do I get this nested type in TS
export declare type ReceiptEnum = {
    Action: {
        actions: Action[]; // Action is a type too. Consider it as a string for the ex.
        gasPrice: string;
        inputDataIds: string[];
        outputDataReceivers: string[];
        signerId: string;
        signerPublicKey: string;
    };
} | {
    Data: {
        data: string;
        dataId: string;
    };
};

I have this above code and I want to cast something which will be of type

const data : ReceiptEnum['Action'] = {}; // This doesn't work

How would I do that in TS? Doing this currentlt throws an error Property 'Action' does not exist on type 'ReceiptEnum'

about 4 years ago · Santiago Trujillo
3 answers
Answer question

0

You cannot refer to a property of a union like that. You will need to declare separate types for them:

interface ReceiptAction {
    actions: Action[];
    gasPrice: string;
    inputDataIds: string[];
    outputDataReceivers: string[];
    signerId: string;
    signerPublicKey: string;
}
interface ReceiptData {
    data: string;
    dataId: string;
}    
export declare type ReceiptEnum = {
    Action: ReceiptAction
} | {
    Data: ReceiptAction;
};

Then you can directly refer to just ReceiptAction.

about 4 years ago · Santiago Trujillo Report

0

TypeScript does, as far as I'm concerned, not support enums containing struct like data (unlike rust, for example) which seems you are trying to recreate here. See the comments

You can't index the type like that. TypeScript does not have1 any information about the union variants until you check which one it is. That's why you can't index it. And even if you could, the resulting type would not be assignable to ReceiptEnum.

But you may still construct your existing type the following way:

const data: ReceiptEnum = {
    Action: {
        gasPrice: "",
        inputDataIds: [],
        outputDataReceivers: [],
        signerId: "",
        signerPublicKey: "",
    },
};

But I normally use a separate field (e.g. type) to distinguish union variants. It's a pretty common pattern in TypeScript to the extent of my knowledge.

export enum ReceiptType {
    Action,
    Data,
}

export interface ActionReceipt {
    type: ReceiptType.Action,
    actions: Action[];
    gasPrice: string;
    inputDataIds: string[];
    outputDataReceivers: string[];
    signerId: string;
    signerPublicKey: string;
}

export interface DataReceipt {
    type: ReceiptType.Data,
    data: string;
    dataId: string;
}

export type Receipt = ActionReceipt | DataReceipt;

// Usage:

const receipt: Receipt = {
    type: ReceiptType.Action,
    actions: [],
    gasPrice: "",
    inputDataIds: [],
    outputDataReceivers: [],
    signerId: "",
    signerPublicKey: "",
};

processReceipt(receipt);

function processReceipt(receipt: Receipt) {
    if (receipt.type == ReceiptType.Action) {
        return processActionReceipt(receipt);
    }

    throw new Error(`processing of receipt type ${receipt.type} not implemented`);
}

function processActionReceipt(receipt: ActionReceipt) {} 
  • 1 TypeScript obviously has some information about the union variants. For example, if they share a common property, you can use that. This is also how my suggestion works.
about 4 years ago · Santiago Trujillo Report

0

Well it makes a lot of sense that TS is throwing that error at you. You're declaring that data is of type Action despite Action having a number of mandatory fieldsthat don't exist in the empty object that is assigned todata`.

If the goal here is to pretend that data is already a valid Action type then what we want to do is something like this:

const data = {} as ReceiptEnum['Action'];

What I recommend you do instead of this though is have all of the fields ready to go ahead of time and then create the Action without pretending as if data already contains the fields that we expect it to contain. So maybe something like this instead:

const actions = alreadyPreparedActions;
const gasPrice = '$5.00';
const inputDataIds = ['a', 'b', 'c'];
const outputDataReceivers = ['d', 'e', 'f'];
const signerId = 'super signer!';
const signerPublicKey = 'ghi';

const data: ReceiptEnum['Action'] = {
    actions,
    gasPrice,
    inputDataIds,
    outputDataReceivers,
    signerId,
    signerPublicKey,
};
about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!