Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

124
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda