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

208
Vistas
Typescript Create a type whose properties are the properties of an interface

I have an interface definition as follows

export interface RoutingMap {
    ticket: {
        id: number
    },
    car: {
        model: string,
        make: number
    }
}

I want to be able to create an interface for an object, which has 2 properties - 1 being a key in the RoutingMap and the other being whatever the type of that Key in the RoutingMap is.

In pseudo-code I image it looking like this

export interface RoutingMessage {
    resource: keyof RoutingMap,
    params: RoutingMap["resource"]
}

The end goal is for me to be able to construct objects like this

const msg: RoutingMessage = {
    resource: "ticket",
    params: { id: 10 }
}

const invalidMsg: RoutingMessage = {
    resource: "something", //TS error - "something" is not a key of routing map
    params: { id: 10 }
}

const invalidMsg2: RoutingMessage = {
    resource: "car"
    params: { model: "tesla", make: true } //TS error - "make" is not a boolean
}

const invalidMsg3: RoutingMessage = {
    resource: "car"
    params: { id: 123 } //TS error - id is not assinable to  {model: string, make: boolean}
}

The RoutingMap is something which would be extended with time, and people should be able to create specific objects, based on the keys (and their values)

As you can see from the pseudo-code example I can set a constraint for the resource, but I need a way to constrain the params property to only allow objects, which match the signature of the Key in the RoutingMap

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Because there are a finite number of keys that match keyof RoutingMap, you can write RoutingMessage as a union of object types where each element of the union corresponds to a particular key, like this:

type RoutingMessage = {
    resource: "ticket";
    params: {
        id: number;
    };
} | {
    resource: "car";
    params: {
        model: string;
        make: number;
    };
}

You can compute RoutingMessage programmatically from RoutingMap by writing it as a "distributive object type" (terminology borrowed from microsoft/TypeScript#47109) where we make a mapped type where each property with key K in RoutingMap is mapped to the desired object type for that key, and then we immediately index into it with keyof RoutingMap, producing the desired union.

type RoutingMessage = { [K in keyof RoutingMap]:
  { resource: K, params: RoutingMap[K] }
}[keyof RoutingMap];

With the above definition, RoutingMessage will gain new union members whenever a new property is added to RoutingMap, as desired.


Let's make sure it behaves how you want:

const msg: RoutingMessage = {
  resource: "ticket",
  params: { id: 10 }
}; // okay

const invalidMsg: RoutingMessage = {
  resource: "something", // error!
  //~~~~~~ <-- Type '"something"' is not assignable to type '"ticket" | "car"'
  params: { id: 10 }
};

const invalidMsg2: RoutingMessage = {
  resource: "car",
  params: { model: "tesla", make: true } // error!
  //  --------------------> ~~~~
  // Type 'boolean' is not assignable to type 'number'.
};

const invalidMsg3: RoutingMessage = {
  resource: "car",
  params: { id: 123 } // error!
  // -----> ~~~~~~~
  // Type '{ id: number; }' is not assignable to type '{ model: string; make: number; }' 
};

Looks good!

Playground link to code

about 4 years ago · Juan Pablo Isaza Denunciar

0

export interface RoutingMessage {
    resource: keyof RoutingMap,
    params: RoutingMap[this["resource"]]
}
about 4 years ago · Juan Pablo Isaza 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