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

230
Vistas
How to use types as values in TypeScript? / Metatypes

I’m working on a component that fetches records from a data source. The component is written in TypeScript which I’m not super comfortable with.

Each record is characterized by a key and the record’s value type. The fetch method takes an instance of RecordDescriptor<Value> whose generic parameter Value determines the method’s return type.

In Swift, I would accomplish the goal with the following code, taking advantage of metatypes:

struct RecordDescriptor<Value> {
    let key: String
    let valueType: Value.Type // `Value.Type` is a metatype, the type of a type
}

func fetchValue<Value>(for descriptor: RecordDescriptor<Value>) -> Value {
    // …
}

let intRecordDescriptor = RecordDescriptor(key: "int_record", valueType: Int.self)
// `Int.self` refers to the `Int` type itself, not an instance of `Int`

let intValue = fetchValue(for: intRecordDescriptor)

Basically I get to specialize the generic parameter Value without using concrete instances of a type—only the type name itself.

How do I achieve the same result in TypeScript?

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

0

You don't care about Metatypes for their type-hinting capabilities, you only care about them for their ability to

access initializers or other static members of the class or protocol

That's quite simply spelled as:

interface Newable {
    new(): any
}

type Constructable<T> =
  T extends Newable
    ? T
    : T extends (...args: any[]) => unknown
      ? T : never

type RecordDescriptor<T, Key extends string> = { key: Key }
  & (
    T extends Constructable<T>
      ? { transformation: T }
      // Replace this arm with `never`
      // to not allow scalars / non-classes like `boolean`
      : { transformation: (arg?: unknown) => T }
    )

Usage is:

let descriptorN: RecordDescriptor<Number, "numbers"> = {
  key: "numbers",
  transformation: Number
}
let resultN: Number = descriptorN.transformation("123")


let descriptorF: RecordDescriptor<(a: string, b: boolean) => string | boolean, "crazy"> =
  { key: "crazy", transformation: (a, b) =>  b ? "hi" : a.length > 3 }
let resultF: string | boolean = descriptorF.transformation("hmm", true)

let rp: RecordDescriptor<boolean, "options"> =
  { key: "options", transformation: () => true }
let resultP: boolean = rp.transformation()

Playground link

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