1

How in typescript create interface of array of key value pair from another interface keys.

typescriptlang sandbox

A have next interfaces:

type KeyValue<K, V> = {
    key: K;
    value: V;
};

interface Features {
    wheels: number;
    color: string;
    packages?: string[];
}

interface Car {
    manufacturer: string;
    model: string;
    features: Features;
}

Next, create variables using this interfaces:

const fordFocus: Car = {
    manufacturer: "ford",
    model: "focus",
    features: {
        wheels: 17,
        color: "white",
    },
};

const bmwX3: Car = {
    manufacturer: "bmw",
    model: "X3",
    features: {
        wheels: 19,
        color: "black",
        packages: ["S08SM", "S08TF", "S08TG", "S0925"],
    },
};

I want to send this variables to server.

Request data should have next schema:

interface CarRequest {
    manufacturer: string;
    model: string;
    features?: {key: string, value: any}[]
}

Now i declare features manually, but i want to do it by utility interface. Like this:

interface FeaturesRequest<T, K in T> {
  [n: number]: {key: K, value: T}
}

Function that prepare request data

function prepareCarRequest(car: Car) {
    const request: CarRequest = {
        manufacturer: car.manufacturer,
        model: car.model,
        features: Object.entries(car.features).map(([key, value]) => ({key, value})),
    };

    return request;
}

I don't understand how i should declare requestData that it pick keys in Feature interface and transform it to KeyValue automatically.

ilya
  • 51
  • 1
  • 9

1 Answers1

0

You can transform your interface into key-value type with a rather simple mapped type:

type InterfaceToKV<T> = {
    [K in keyof T]: { key: K, value: T[K] }
}[keyof T]

TS playground

But the Object.entries' type is more generic (discussion is about Object.keys but the same applies to Object.entries) and will not allow you to assign string to your key literal types.

aleksxor
  • 7,535
  • 1
  • 22
  • 27