1

I have a class with a number of private properties with various types for which I want to create one generic public Set method.

class A {

  private prop1: Array<A> = new Array()
  private prop2: Array<[A,A]> = new Array()
}

// Set method that can be used in following way: 
// a.Set('prop1', new Array<A>())
// a.Set('prop2', new Array<[A, A]>())
// but not:
// a.Set('prop3', ...)
// a.Set('prop1', 23)

Essentially, I want a Set method that has: The first parameter restricted to a set of private properties of A. Ideally automatically enumerated but since keyof doesn't handle private properties a handwritten set is fine (e.g. type AProps = 'prop1'|'prop2'). The second parameter restricted to the type of the property corresponding to the first parameter.

I.e. something like this (I know this doesn't work) where PropType<A, property>) selects correct dependent type of of union of all possible PropTypes of A:

type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
class A {

  private prop1: Array<A> = new Array()
  private prop2: Array<[A,A]> = new Array()

  public Set(property: keyof A, value: PropType<A, property>) {
    this[property] = value
  }

I'm 90 % sure it can't be done within current TS typesystem in a reasonably typesafe manner.

While decorator might be helpful, it's not (yet) usable due to inability to modify target's class/interface: https://github.com/microsoft/TypeScript/issues/4881


I know that I can create the setter methods by hand. I also know that I can create one that will use a trick similar to this. I'm not asking about that. I know there're many workarounds.

Petrroll
  • 741
  • 7
  • 29
  • Related https://github.com/microsoft/TypeScript/issues/13543 – Aleksey L. Apr 19 '20 at 14:47
  • Yep, I've seen that one. But even if that was possible I think it would still not be doable due to the second issue of having to have dependent type. – Petrroll Apr 19 '20 at 16:20
  • No, the only "problem" here is that `keyof` doesn't return private members. With public keys no problem at all https://www.typescriptlang.org/play?#code/MYGwhgzhAECC0G8CwAoa0AOAnA9hgjAFxxZZgCeAPLAHzQC80AdgKYDuJZ5AFAJSqp0GAK4AjEAEtg0CCwAulANLQWADzksmAExgBrFuRwAzaHIAWEiDW7Y8LLHPLFFAGmgA3MCGEti5ywDaigC6vIiC6KYWEAG2GPaOwQweXj4RAL6omSiorBywfAB0snLcAORx+GVuAaFAA – Aleksey L. Apr 20 '20 at 05:44
  • Ah, I see. Didn't realize you can do that, but it makes perfect sense that you can :). Write it as a quick answer and I'll be happy to accept it. – Petrroll Apr 20 '20 at 13:49
  • It's not just an issue of `keyof`, this approach doesn't work with private properties even if the type is manually created instead of synthesized via `keyof`. https://www.typescriptlang.org/play/#code/PTAEBEHsFMGcDsDkAXUB3SAnA1gWAFDICeADtKAIIAKmAlgG4CGy5AvKAEQmaQkCMHUAQDGAG0axYlUAG8CoUNwbNy3XnwBclTJkZEAPBQB8odvGhptuogAoAlAXmKArgCNRtYaFjRk+gNKg0AAeLPAAJlLUdEwsRjZqZJjEWv4ANKBMos7QWsgAFrSwANr+ALp2sk4KBUXFidDJRGWmmYzZ0E4AvgQ9+OaWFPYAdD7INoiJfIgZxRWO+CCUorCQ6FjYsATEZKAAQlRuHl7sXDz8giLikvtV+AokR56K55pWeoYmZhbvtg74Tke7meYwCQVC0AiUgOT2E8QaTVSGSyOTyhRK5UqcnuClAtRKCOILXYKM6OL6fQGlBGYwmUxmoDm-yAA – Petrroll Apr 20 '20 at 14:07
  • Of course it won't work. In order to use index access operator the key should be valid key of type. Again - `keyof` issue – Aleksey L. Apr 20 '20 at 17:19

0 Answers0