objektsdestrukturering - Typescript-konstruktörkortkommandon för namngivna parametrar


Det har gått ett tag sedan konstruktörsförkortningen introducerades, och den är verkligen användbar. Nu kan jag skriva detta:

class Dog {
  constructor(
    public age: number,
    public weight: number,
  ) {}
}

istället för detta:

class Dog {
  public age: number
  public weight: number

  constructor(
    age: number,
    weight: number,
  ) {
    this.age = age
    this.weight = weight
  }
}

Och det fungerar ännu bättre för mer komplexa klasser.

Jag undrar om det finns någon förkortning för klasskonstruktör med namngivna parametrar (med objektavbrytning)? Jag tycker new Dog({age: 3, weight: 8}) är mycket tydligare än new Dog(3, 8). Ingen risk att argumenten kommer i fel ordning. Men klassdefinitionen för detta ser verkligen ful ut:

class Dog {
  // 1. declare properties
  public age: number
  public weight: number

  constructor({
    // 2. object destructing
    age,
    weight,
  }: {
    // 3. declare object type
    age: number,
    weight: number,
  }) {
    // 4. assign values
    this.age = age
    this.weight = weight
  }
}
// x4 duplicates, no DRY at all

Svar #1

Nej, det finns inte och kommer förmodligen aldrig att göra det.

Egenskapsdefinitioner på konstruktörnivå kallas Parameter properties.

Dessa parameter-egenskaper är en av de avvikelser där TypeScript inte bara skriver typning över JS utan också genererar viss kod.

class Dog {
  constructor(
    public age: number,
    public weight: number,
  ) {}
}

genererar följande JS

class Dog {
    age;
    weight;
    constructor(age, weight) {
        this.age = age;
        this.weight = weight;
    }
}

Det du frågar efter new Dog({age: 3, weight: 8}) & new Dog(3, 8) är helt olika.

En är ett objekt som inte har någon betydelse i JS och den andra är vad som händer vid körning.

Bortsett från några få undantag är TS inte avsedd att generera kod åt dig.

Svar #2

Det finns ingen syntax för det, men du kan göra det mer DRY genom att införa ett gränssnitt och slå ihop det med klassen:

Lekplats

interface DogProps {
    age: number,
    weight: number,
}
interface Dog extends DogProps {}
class Dog {
    constructor(props: DogProps){
        Object.assign(this, props);
    }
    feed(){
        console.log('Thank you, my Snack Lord');
    }
}

const dog = new Dog({age: 3, weight: 20});
dog.age // number