Разрешить динамический тип одного свойства на основе значения другого строкового свойства

Привет, я не уверен, возможно это или нет, но если это невозможно, предложите мне несколько альтернативных способов добиться этого.

Я хочу установить тип свойства объекта в интерфейсе, в котором объект может иметь любые свойства, но должен иметь свойство, названное со значением другого свойства в этом интерфейсе. Давайте рассмотрим случай

interface ListGroupProps {
  data: {[x:string]:any} & {[valueProperty]:any};
  valueProperty:string;
}

Теперь рассмотрим объект с допустимым типом

{
    data:{id:1, textValue: "hello world"},
    valueProperty: "textValue",
}

Вот объект с недопустимым типом

{
    data:{id:1, textValue: "hello world"}, // someOtherPropertyName in not present here
    valueProperty: "someOtherPropertyName",
}

Было бы лучше, если бы можно было обойтись без универсальных типов


person Subhashis Pal    schedule 30.08.2020    source источник


Ответы (1)


Это возможно сделать, но вы должны использовать дженерики:

interface ListGroupProps<K extends (string extends K ? never : keyof any)> {
    data: { [x: string]: any } & { [x in K]: any };
    valueProperty: K;
}

const x: ListGroupProps<'textValue'> = {
    data: { id: 1, textValue: "hello world" },
    valueProperty: "textValue",
} as const;

const y1: ListGroupProps<'textValue'> = {
    data: { id: 1, textValue: "hello world" },
    valueProperty: "someOtherPropertyName", // Error on `valueProperty`
};

const y2: ListGroupProps<'someOtherPropertyName'> = {
    data: { id: 1, textValue: "hello world" }, // Error on `data`.
    valueProperty: "someOtherPropertyName",
};

const y3: ListGroupProps<string> = { // Error on `string`.
    data: { id: 1, textValue: "hello world" },
    valueProperty: "someOtherPropertyName",
};

Playground Link

person Mingwei Samuel    schedule 07.09.2020
comment
Большое спасибо. Это будет решением моей проблемы. Дженерики в порядке. Я могу принять это. Спасибо. - person Subhashis Pal; 08.09.2020