1

I have deeply nested objects like this (with more than 3 levels):

{
    a1: 'foo1',
    b1: [
        {
            c2: 'foo2',
            d2: [
                {
                    e3: 'foo3',
                    f3: 'foo3'
                },
                {
                    e3: 'bar3',
                    f3: 'bar3'                    }
            ]
        }
    ]
};

and I've created nested interfaces like so:

export interface Level3 {
    e3: string;
    f3: string;
}

export interface Level2 {
    c2: string;
    d2: Level3[];
}

export interface Level1 {
    a1: string;
    b1: Level2[];
}

I'm transforming the most deeply nested object to something else, while leaving everything the upper structure untouched. For example:

export interface Level3Transformed {
    e3Transformed: number[];
    f3Transformed: number[];
}

export interface Level3 {
    e3: string;
    f3: string;
}

When I declare a Level1Transformed interface that is otherwise the same as Level1, but has Level3Transformed instead of Level3, is there any way to reuse all the in-between interfaces (like Level2)?

Or is there some other smart way to structure / declare similar nested objects like this while avoiding a lot of duplicate interfaces?

Edit: without using the OR operator?

1
  • 1
    Not sure but can we not try something like this: interface level { [key: string]: string | Array<Level>}? And to answer is there any way to reuse, yes. You are already exporting interfaces. Just import them and use as required Commented Apr 6, 2018 at 12:46

3 Answers 3

3
  export interface Level2 {
     c2: string;
     d2: Level3[] | Level3Transformed[];
 }

Or you could use generic types:

 export interface Level2<T> {
   c2: string;
   d2: T[];
 }

 export interface Level1<T> {
   a1: string;
   b1: Level2<T>[];
 }

And then either

  Level1<Level3>

or

 Level1<Level3Transformed>
Sign up to request clarification or add additional context in comments.

3 Comments

I'd rather have duplicated interfaces than a not-that-useful interface with OR. But the generic type is interesting! I can't think of a way to make this work with more than 3 levels though :(
Duh, brain fart! Awesome, thanks, TIL about generic types :)
@usagidon glad to help :)
2

You can simply give OR operator in level2

export interface Level2 {
    c2: string;
    d2: Level3[] | Level3Transformed[];
}

This way your level1 type object will be level3 or level3transformed type.

Comments

1

You can use template types, e.g.:

export interface Level3<T> {
    e3: T;
    f3: T;
}

export interface Level2<T> {
    c2: string;
    d2: Level3<T>[];
}

export interface Level1<T> {
    a1: string;
    b1: Level2<T>[];
}

Then you can have Level1<string> or Level1<number[]>.

If you want to change even the names of properties in Level3, you can pass the whole Level3 as a template type, down to Level2.

Note that you can also define a default value for T, e.g. export interface Level1<T=string>, then you can use just Level1 for the string version, or Level1<number[]> for a modified version.

Comments

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.