Aurospire
Aurospire

Reputation: 63

Is there a way to dynamically map keys to getters/setters of different types in Typescript?

I can create a type with different types for getter/setters like so:

type Example = {
   get prop(): number;
   set prop(value: any);
}

I can also map keys to different values:

type Mapped<T extends Object> = {
    [Key in keyof T]: T[Key] | boolean;
}

Is there a way to map keys to getters/setters? Something like:

type MappedAccessors<T extends Object> = {
    get [Key in keyof T](): T[Key];
    set [Key in keyof T](value: any);
}

Upvotes: 6

Views: 1475

Answers (2)

jcalz
jcalz

Reputation: 328196

No, this is currently not possible as of TypeScript 4.8. As you mention, TypeScript supports variant accessors, also known as separate write types on properties, as long as the get type is assignable to the set type. You're using any as the set type so that's not a problem.

But there is no current way to use variant accessors in mapped types. There is an open feature request for this at microsoft/TypeScript#43826. It's marked as "Awaiting More Feedback", which means they want to hear more community input in favor of it before they consider implementing it. You may want to go there, give it a 👍, and explain your use case, why it's compelling, and why the existing workarounds aren't sufficient. It's not likely that a single additional comment there would make much difference, but it couldn't hurt.

Upvotes: 3

Behemoth
Behemoth

Reputation: 9310

I know these are not real getters and setters but it mimics the behaviour.

type Example = {
  prop: number;
};

type Mapped<T> = {
  [K in keyof T as `get${Capitalize<K & string>}`]: () => T[K];
} & {
  [K in keyof T as `set${Capitalize<K & string>}`]: (
    value: T[K]
  ) => void;
};

type MappedExample = Mapped<Example>;

// type MappedExample = {
//   getProp: () => number;
//   setProp: (value: number) => void;
// }

Upvotes: 2

Related Questions