wkrueger
wkrueger

Reputation: 1363

Adding a new property to an object type without runtime code

type FormerActions =
  | {
      type: "ACTION_A"
      payload: string
    }
  | {
      type: "ACTION_B"
      payload: number
    }

type Converter = ...

type ModifiedActions = Converter<FormerActions, "group", "DOMAIN">

//should output
type ModifiedActions =
  | {
      group: 'DOMAIN'
      type: "ACTION_A"
      payload: string
    }
  | {
      group: 'DOMAIN'
      type: "ACTION_B"
      payload: number
    }

I want to write a Converter "type function" that takes the arguments as listed above and outputs a type equal (or structurally equal) to ModifiedActions.

I know I can probably used mapped types to add the property and maybe conditional types can work on the distributive | thing?

Upvotes: 1

Views: 35

Answers (1)

jcalz
jcalz

Reputation: 327884

Try

type Id<T> = {[K in keyof T]: T[K]}  
type Converter<T, K extends string, V> = T extends any ? Id<Record<K, V> & T> : never

maybe?

enter image description here

The idea is indeed to distribute over the type T with T extends any ? ..., and then to merge each constituent with Record<K, V> from the standard library. Finally, I used Id<T> which just walks through a type and outputs it as key-value pairs.

All that being said, that type is essentially equivalent to just Record<K, V> & T, I think. The distributing and merging is just to be pretty (and maybe avoid some odd edge cases, although it adds some too.)

Hope that helps. Good luck!

Upvotes: 2

Related Questions