1

Can I (somehow?) forbid the skipping of optional parameter in typescript?

class MyList {
  constructor(
    public head?: number,
    public tail?: MyList
  ){}
}

const L0 = new MyList();              // <--- empty element list - good !
const L1 = new MyList(888);           // <--- single element list - good !
const L2 = new MyList(777, L0);       // <--- general list - good !
const L3 = new MyList(undefined, L1); // <--- forbid this 

I want to statically enforce the following property on my list:

  • If head is undefined then tail is also undefined (and the list is empty)

Any TypeScript trick to achieve that? (This question is complementary to this question)

gre_gor
  • 6,669
  • 9
  • 47
  • 52
OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87
  • @gre_gor You might skipped the _"if head is undefined then tail is also undefined (and the list is empty)"_ line. I thought that adding the empty list variable adds more clarification which some people might not get. Also the OP accepted the change. – bobkorinek Jan 11 '23 at 06:22

1 Answers1

2

You can use something called overloading. This works for both methods and functions in TS. The basic idea is that you have single function/method implementation with all the possible arguments and you can specify different combintations of the function's arguments (just like for your case where you can have 0 arguments, only the first or both).

class MyList {
  constructor()
  constructor(head: number)
  constructor(head: number, tail: MyList)
  constructor(
    public head?: number,
    public tail?: MyList
  ){}
}

const L0 = new MyList(888);
const L1 = new MyList(777, L0);   
const L2 = new MyList(undefined, L1); // This will show error: Argument of type 'undefined' is not assignable to parameter of type 'number'.
bobkorinek
  • 646
  • 3
  • 16
  • Ah I was sure constructor overloading is forbidden in TypeScript (?) – OrenIshShalom Jan 11 '23 at 06:27
  • 1
    @OrenIshShalom It shouldn't matter actually: either one of the declarations matches or none of them. TS matches the constructor's declarations based on how many arguments you pass _and_ what types do the passed arguments have. Take your case: it shouldn't matter if the _empty list_ declaration is first or last; TS will match the empty list when you call the constructor with no arguments and other declarations will be ignored (because they all have at least one argument). – bobkorinek Jan 11 '23 at 06:44