Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

typescript - Destructured parameter properties in constructor

Typescript allows parameter properties

class ParameterProperty {
  constructor(private member: number) {}
}

The above creates a class with private member member, the constructor sets this.member to the first argument of the constructor.

But there is no equivalent for 'named parameters' via destructuring.

interface DestructedOptions {
  prefix: string;
  suffix: string;
}

class Destructed {
  constructor({private prefix, private suffix}: DestructedOptions) {}
}

The above doesn't work, you have to do something like this:

class Destructed {
  private prefix: string
  private suffix: string
  constructor({prefix, suffix}: DestructedOptions) {
    this.prefix = prefix;
    this.suffix = suffix;
  }
}

which is really verbose and requires updates to three places when adding a new property to DestructuredOptions. I tried something similar, using mapped properties

class Destructed {
  private [P in keyof DestructedOptions]: T[DestructedOptions];
  constructor(opts: DestructedOptions) {
    Object.assign(this, opts)
  }
}

Only to find out that mapped properties can only be used in Types, not interfaces or classes. I don't like this option anyway since it copies everything from opts, I would really want something like this:

class Destructed {
  constructor(opts: DestructedOptions) {
    for (let key in keyof DestructedOptions) {
      this[key] = opts[key];
    }
  }
}

But of course typescript doesn't let you get runtime values from Types.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What about:

class Destructed {
    private prefix: string;
    private suffix: string;

    constructor(opts: DestructedOptions) {
        Object.assign(this, opts);
    }
}

Also, there's an open issue on this: Combining destructuring with parameter properties


Edit

If you want to avoid re-writing the properties in the class then you'll need to make the members public, when that's the case then the solution is as shown in the issue I linked to:

class Destructed {
    constructor(opts: DestructedOptions) {
        Object.assign(this, opts);
    }
}

interface Destructed extends DestructedOptions { }

let destructed = new Destructed({ prefix: "prefix", suffix: "suffix" });
console.log(destructed.prefix);
console.log(destructed.suffix);
console.log(destructed.DoesntExist); // error

(code in playground)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...