2

Is there a way to mitigate the order of optional parameters in TypeScript? I currently have the class

export default class Area {
    private name: string;
    private description: string;
    private item?: Item;
    private hazard?: Hazard;

    constructor(name: string, description: string, item?: Item, hazard?: Hazard) {
        this.name = name;
        this.description = description;
        this.item = item;
        this.hazard = hazard;
    }
}

For this Area class, I required the name and string parameters but not the item or hazard parameters. I tried instantiating an Area object in the following ways:

let item = new Item(); // had required parameters, but not important for now
let hazard = new Hazard(); // had required parameters, but not important for now

let area = new Area("test", "test"); // works as expected
let area1 = new Area("test", "test", item); // works as expected
let area2 = new Area("test", "test", hazard); // DOES NOT WORK as expected
let area3 = new Area("test", "test", item, hazard); // works as expected

Even though hazard and item are optional, if I want to omit item, I need to pass in undefined for the third parameter. Is there anyway to mitigate or forego this behavior, where we can pass in a third argument that matches any of the optional parameters?

1
  • 2
    No this is not possible in javascript/typescript. What you can do is change constructor to accept object like { name: string, description: string, item?: Item, hazard?: Hazard } Commented Apr 19, 2020 at 7:05

1 Answer 1

3

The type-checking done by Typescript exists only in Typescript- it doesn't exist in the compiled Javascript, so if that was allowed, there wouldn't be any way for Javascript to determine which argument you're actually trying to pass.

Instead, pass an optional object which may have the item or hazard properties:

class Item{}
class Hazard{}

export default class Area {
    private name: string;
    private description: string;
    private item?: Item;
    private hazard?: Hazard;

    constructor(
      name: string,
      description: string,
      obj: { item?: Item, hazard?: Hazard } = {}
    ) {
        this.name = name;
        this.description = description;
        if (obj.item) this.item = obj.item;
        if (obj.hazard) this.hazard = obj.hazard;
    }
}

const item = new Item();
const hazard = new Hazard();

const area = new Area("test", "test"); 
const area1 = new Area("test", "test", { item });
const area2 = new Area("test", "test", { hazard });
const area3 = new Area("test", "test", { item, hazard });
Sign up to request clarification or add additional context in comments.

1 Comment

For more context, converting named parameters to structured parameters is a common pattern in typescript. It's common enough that there's a language level refactor tool for it - github.com/microsoft/TypeScript/issues/23552

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.