У меня есть два интерфейса, и я хотел бы объединить только идентификаторы интерфейсов

#typescript

Вопрос:

Я пытаюсь обновить свойство, вложенное в массив объектов, и у этого объекта есть другой массив объектов. Чтобы обновить свойство, мне нужны идентификаторы (или индексы) обоих массивов для обновления свойства. Поэтому я создал интерфейсы:

 export interface ILaser {
    id: 'L1' | 'L2' | 'L3' | 'L4' | 'L5' | 'L6';
    name:
        | 'Laser #1'
        | 'Laser #2'
        | 'Laser #3'
        | 'Laser #4'
        | 'Laser #5'
        | 'Laser #6';
    switchMode: Number;
    pulseWidth: Number;
    power: Boolean;
}

export interface IOpticalHeadUnit {
    id: 'OHU1' | 'OHU2' | 'OHU3';
    name:
        | 'Optical Head Unit #1'
        | 'Optical Head Unit #2'
        | 'Optical Head Unit #3';
    lasers: Array<ILaser>;
}
 

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

Что-то вроде этого:

 interface ILaserIdAndIOpticalUnitId{
laserId: ILaser.id;
opticalHeadUnitId: IOpticalHeadUnit.id;
 

Можно ли это сделать в машинописном виде?

Комментарии:

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

Ответ №1:

Вам нужно использовать обозначения в квадратных скобках, как и в обычном js:

 export interface ILaser {
    id: 'L1' | 'L2' | 'L3' | 'L4' | 'L5' | 'L6';
    name:
    | 'Laser #1'
    | 'Laser #2'
    | 'Laser #3'
    | 'Laser #4'
    | 'Laser #5'
    | 'Laser #6';
    switchMode: Number;
    pulseWidth: Number;
    power: Boolean;
}

export interface IOpticalHeadUnit {
    id: 'OHU1' | 'OHU2' | 'OHU3';
    name:
    | 'Optical Head Unit #1'
    | 'Optical Head Unit #2'
    | 'Optical Head Unit #3';
    lasers: Array<ILaser>;
}

interface ILaserIdAndIOpticalUnitId {
    laserId: ILaser['id'];
    opticalHeadUnitId: IOpticalHeadUnit['id']
}
 

Игровая площадка

Комментарии:

1. Спасибо, это то, что я искал, и игровая площадка была отличным бонусом, я проверил ее там, и она работает так, как я хотел

Ответ №2:

Простое исправление с использованием индексированных типов доступа:

 interface ILaserIdAndIOpticalUnitId {
  laserId: ILaser['id'];
  opticalHeadUnitId: IOpticalHeadUnit['id'];
}

const foo: ILaserIdAndIOpticalUnitId = {
  laserId: 'L1',
  opticalHeadUnitId: 'OHU1'
};
 

Из любопытства, тип пересечения:

 type ID = ILaser['id'] | IOpticalHeadUnit['id'];
const foo: ID = 'L1';
const bar: ID = 'OHU1';