skip to Main Content

I have a class with a destructured constructor parameter:

import * as ē from 'three'

export class cylindricCurve extends ē.Curve {
   #scale: number
   #eqs: ((θ: number) => number)[]
   #rounds: number
   #mainAxis: 'x' | 'y'
   constructor({
      eqs,
      scale = 1,
      rounds = 1,
      mainAxis = null,
   }: {
      eqs: ((θ: number) => number)[]
      scale: number
      rounds?: number
      mainAxis?: 'x' | 'y'
   }) {
      super()
      this.#scale = scale
      this.#eqs = eqs
      this.#rounds = rounds
      this.#mainAxis = mainAxis
   }

As you can see, this is incredibly verbose, with every name mentioned FIVE times just to initialize member variables. I wonder if there is a more concise way to achieve the task.

2

Answers


  1. Chosen as BEST ANSWER

    After finding an eight years old issue in TypeScript (https://github.com/Microsoft/TypeScript/issues/5326), I tried to follow one of the workarounds:

    import * as ē from 'three'
    
    export class cylindricCurve extends ē.Curve {
       private scale: number = 1
       private eqs: ((a: number) => number)[]
       private rounds?: number = 1
       private mainAxis?: 'x' | 'y' = null
    
       constructor(_: cylindricCurve) {
          super()
          Object.assign(this, _)
       }
    }
    

    While this works, I am not too happy with this approach, which looks unnecessarily hacky, and lacks flexibility: every property now is doomed to be a valid constructor argument.


  2. It’s hard to prove a negative, but while you can get rid of one of them by not destructuring, I think you’re stuck with the other ones because you can’t auto-declare-and-initialize a private field from a constructor parameter (like you can with TypeScript’s public, protected, and private parameter annotations; and even those you’d have to have discrete parameters for rather than destructuring).

    Here’s that minor change, just for completeness:

    import * as ē from 'three'
    
    export class cylindricCurve extends ē.Curve {
       #scale: number
       #eqs: ((θ: number) => number)[]
       #rounds: number
       #mainAxis: 'x' | 'y'
       constructor(props: {                         // ***
          eqs: ((θ: number) => number)[]
          scale: number
          rounds?: number
          mainAxis?: 'x' | 'y'
       }) {
          super()
          this.#scale = props.scale ?? 1            // ***
          this.#eqs = props.eqs                     // ***
          this.#rounds = props.rounds ?? 1          // ***
          this.#mainAxis = props.mainAxis ?? null   // ***
       }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search