'Type Script Class Input Interface with optional params

So I'm fighting the compiler here a bit and wanted to see where I'm going wrong or if I'm just chasing an anti-pattern and should change the approach.

What I would like is to be able to have a class with required parameters, and an input interface with optional parameters. If the Input doesn't have a given parameter the class constructor computes a sensible default.

interface PersonInput {
  name?: string;
  age?: number;
}

class Person {
  name: string;
  age: number;
  constructor(input: PersonInput) {
    this.name = "Zach";
    this.age = 30;
    for (const key in input) {
      this[key] = input[key]; // <--- Errors here with 
    }
  }
}
// test.ts:13:19 - error TS7053: Element implicitly has an 'any' type because 
// expression of type 'string' can't be used to index type 'PersonInput'.

Okay that's fine what if I assert that the element will not have an any type associated with it.

\\ ...snip
    for (const key in input) {
      const personParam: keyof Person = key; // <-- Type 'string | number | undefined' is not assignable to type 'never'
      this[personParam] = input[personParam];
    }
\\...snip

So in my case I just avoided the spread of properties and did something like this:

//...snip
class Person {
  name: string;
  age: number;
  constructor(input: PersonInput) {
    this.name = input.name || "Zach";
    this.age = input.age || 30;
  }
}

What am I doing wrong?

Addenum

I've also been reading about the param! syntax is that needed for this case? I wouldn't think so because the loop will only run with that parameter if it has been defined, its never dependent on a property being passed in the input



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source