dhilt
dhilt

Reputation: 20744

Is it possible to make generic mapped object type in TypeScript?

I have two similar groups of typescript definitions:

enum Operation1 {
  eof = 'eof',
  bof = 'bof'
}
type OperationConfig1 = { [key in Operation1]: TestBedConfig };

enum Operation2 {
  append = 'append',
  prepend = 'prepend'
}
type OperationConfig2 = { [key in Operation2]: TestBedConfig };

I can use them as following:

const config1: OperationConfig1 = {
  [Operation1.eof]: { ... },
  [Operation1.bof]: { ... }
};

const config2: OperationConfig2 = {
  [Operation2.append]: { ... },
  [Operation2.prepend]: { ... }
};

I want to replace OperationConfig1 and OperationConfig2 with one generic type OperationConfig accepting Operation as a parameter in some form like

type OperationConfigGeneric<T> = { [key in T]: TestBedConfig };

const config1: OperationConfigGeneric<Operation1> = { ... };
const config2: OperationConfigGeneric<Operation2> = { ... };

The above code is invalid and throws following exception:

TS2322: Type 'T' is not assignable to type 'string | number |
symbol'. Type 'T' is not assignable to type 'symbol'.

The question. How can I parametrize mapped object type (OperationConfigGeneric)? Or is there any convenient alternative?

Upvotes: 1

Views: 96

Answers (1)

kaya3
kaya3

Reputation: 51043

You can do this, but it is only possible when the type parameter T is something that can be a property key. So, if you declare T with PropertyKey as an upper bound, it works.

type OperationConfigGeneric<T extends PropertyKey> = {
    [key in T]: TestBedConfig
};

const config1: OperationConfigGeneric<Operation1> = { ... };

Upvotes: 1

Related Questions