Home > front end >  In Typescript, how do I set the type of an object to reflect a list of a class's properties?
In Typescript, how do I set the type of an object to reflect a list of a class's properties?

Time:10-29

This example is made generic and simple, the underlying goal is more complicated but understanding how this would be done is important.

Say I have a class

class Foo {
  bar: string;
  baz: number;

  bad() {
    return true;
  };
}

and I have a function

const init(options: InitOptions, bar?: string, baz?: number) {
  const foo = new Foo();
  foo.bar = bar ?? options.fallbacks.bar;
  foo.baz = baz ?? options.fallbacks.baz;
}

How do I create the type InitOptions such that it acts like this

type InitOptions = {
  fallbacks = {
    bar: string;
    baz: number;
  }
}

but without having to repeat myself. ex. fallbacks should be an object where each key is a property from Foo.

CodePudding user response:

Isn't it as easy as?

class InitOptions 
{
  fallbacks: Foo;
}

Updated after clarification:

{
  fallbacks: Pick<Foo, keyof Foo>;
}

CodePudding user response:

Why not use good old OO inheritance paradigm?

class Fooable {
  bar: string = '';
  baz: number = 0;
}

class Foo extends Fooable {
  bad() {
    return true;
  }
}

class InitOptions {
  fallbacks: Fooable = { bar: '', baz: 0 };
}

function init(options: InitOptions, bar?: string, baz?: number) {
  const foo = new Foo();

  foo.bar = bar ?? options.fallbacks.bar;
  foo.baz = baz ?? options.fallbacks.baz;

  console.log(`Initialized with bar: ${foo.bar}, baz: ${foo.baz}`);
}

init({ fallbacks: { bar: 'Hello', baz: 123 } });
init({ fallbacks: { bar: 'Hello', baz: 123 } }, 'World', 456);

When run with ts-node 10.2.1 it gets:

Initialized with bar: Hello, baz: 123
Initialized with bar: World, baz: 456
  • Related