Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript: accessing type information at runtime

If one creates dynamic properties based on parameter inputs:

type ObjBuilder<Prop1 extends string, Prop2 extends string> = {
  [P in Prop1 | Prop2]: P extends Prop2  ? ()=>boolean : ()=>string
}

function objectBuilder<Prop1 extends string, Prop2 extends string>(
  prop1: string,
  prop2: string,
) : ObjBuilder<Prop1, Prop2> {
  return {
    [prop1]: () => true,
    [prop2]: () => prop2,
  } as ObjBuilder<Prop1, Prop2>
}

// note the duplication of information in this code
const a = objectBuilder<'p1', 'p2'>('p1', 'p2')

console.log(a.p1()) // true
console.log(a.p2()) //'p2'

Is it possible to access the type definitions in the function definition to avoid the duplication of objectBuilder<'p1', 'p2'>('p1', 'p2') and rather only have objectBuilder<'p1', 'p2'>() with the compiled javascript having access to the strings p1 and p2?

In other words, have the JavaScript somehow via reflection access the type information and make it available at runtime?

code here

like image 230
TrevTheDev Avatar asked Sep 01 '26 22:09

TrevTheDev


1 Answers

You can infer literal type of arguments.

COnsider this example:

type ObjBuilder<Prop1 extends string, Prop2 extends string> = {
  [P in Prop1 | Prop2]: P extends Prop2 ? () => boolean : () => string
}

function objectBuilder<Prop1 extends string, Prop2 extends string>(
  prop1: Prop1,
  prop2: Prop2,
): ObjBuilder<Prop1, Prop2> {
  return {
    [prop1]: () => true,
    [prop2]: () => prop2,
  } as ObjBuilder<Prop1, Prop2>
}

const a = objectBuilder('p1', 'p2')
console.log(a.p1())
console.log(a.p2())

Playground

As you might have noticed, I have used Prop1 and Prop2 generics as an argument type instead of string. In this way TS is able to infer literal type.

If you are interested in this topis (function arguments type inference) you can check my article

like image 160
captain-yossarian Avatar answered Sep 03 '26 20:09

captain-yossarian