简体   繁体   中英

Extend nested typescript interface

I have some complicated typescript types that get created with a code generator, and I want to be able to use parts of those types without having to define the whole thing again.

For example, my generated interface may look like this (massively simplified)

type Transportation = {
  vehicle: { 
    truck: {...}
    car: {
      make: string
      model: string
      weight: string
      ...
    }
  }
  boat: {...}
  ...
}

Now say I'm writing a function that takes a car and does something with it

/* This type won't work, I'm asking if there is a proper way to do this*/
processCar(car: Transportation.vehicle.car) {
  //TODO: process the car
}

const transport: Transportation = {...}
processCar(transport.vehicle.car)

Is there a way to make a type based on part of an existing type without having to define the whole car item as its own type or interface? Can it be extended with an interface or something? Thanks!

And for context my complex generated types are coming from the graphql code generator . There are some customizations that can be made to it, but unfortunately I don't know of a way to make it generate everything in nice compartmentalized interfaces.

using Transportation['Vehicle']['Car'] does the trick.

A better way to type it would be, if the types are accessible and then you can use them as follows.

you can use namespaces like this

namespace Transportation {
    export namespace Vehicle {
        export interface Car {
            make: string;
            model: string;
            weight: string;
            ...
        };
        export interface Truck {
            make: string;
            model: string;
            weight: string;
            ...
        }
    }

    export interface Boat {
        ...
    }
}

let car: Transportation.Vehicle.Car;

But honestly, this approach doesn't seem to be the best case.

Usually you would just use one namespace and export every interface that you need outside.

namespace Transportation {
    //note, that the Vehicle isn't exported
    interface Vehicle {
        make: string;
        model: string;
        weight: string;
        ...
    }
    export interface Car extends Vehicle {
        doors: number;
    }
    export interface Truck extends Vehicle {
        transportmass: number;
    }

    export interface Boat {
        ...
    }
}

//let car: Transportation.Vehicle.Car; this won't work anymore
//let vehicle: Transportaion.Vehicle; won't work either
let car: Transportation.Car;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM