Nested Pick of object properties

1.2k Views Asked by At

I have some code that looks like this simplified example:

interface Foo {
    x: string;
    y: string;
}

interface Bar {
    a: string;
    b: number;
    foo: Foo
}

function printStuff(bar: Bar) {
    console.log(bar.a);
    console.log(bar.foo.x);
}

In my unit tests, I want want to call printStuff with the bare minimum parameters: {a: 'someval', foo: {x: 1}}. I don't want to construct an object with the complete parameter set for both Foo and Bar.

I realize I can write the parameter signature of printStuff as an anonymous interface, but then it's disconnected from any changes that occur to Foo and Bar. And it can get verbose if I use more properties from the parameter.

Can I instead use Pick to define the exact properties my function takes?

1

There are 1 best solutions below

0
Robert Penner On

There are several ways to slice and dice this with type or interface.

Here's a granular approach that avoids anonymity and maintains relationships:

interface FooX { x: number; }
interface FooY { y: number; }

interface BarA { a: string; }
interface BarB { b: string; }

interface SlimBar extends BarA {
    foo: FooX;
}

interface Foo extends FooX, FooY {}

interface Bar extends BarA, BarB {
    foo: Foo;
}

function printStuff(bar: SlimBar) {
    console.log(bar.a);
    console.log(bar.foo.x);
}

const stuff = { a: 'someval', foo: { x: 1 } };
printStuff(stuff);

Try it in TypeScript Playground

Or you can skip the extra types and cast as any:

function printStuff(bar: Bar) {
...
printStuff(stuff as any);