3

I am trying to construct a typing for an object where for property key "_vars" it must be a Record<string, any>, but for all other property keys (that are not "_vars"), it must be a string.

Something like this:

    interface XY {
      _vars?: Record<string, any>;
      [k:string]: string; // should exclude _vars
    }

But the above doesn't work, reporting TS error: Property '_vars' of type 'Record<string, any> | undefined' is not assignable to 'string' index type 'string'

Is there any way this can be achieved in Typescript?

Thanks in advance!

Andrew Ooi
  • 309
  • 1
  • 3
  • 10
  • There is no perfect way to do this; see the linked question and its answers for the various workarounds. – jcalz Jul 19 '23 at 12:49

1 Answers1

0

You could use an intersection type, along with a function to create a value of that type.

type XY = Record<string, string> & {_vars?: Record<string, any>};
const createXY = (obj: Record<string, string> & {_vars?: never}, _vars?: Record<string, any>): XY => Object.assign({}, obj, {_vars});
const o = createXY({a: '1'}, {x: 2}); // {a: '1', _vars: {x: 2}}
Unmitigated
  • 76,500
  • 11
  • 62
  • 80