Typescript: установка свойства для определенного типа

Я очень новичок в Typescript, просто изучаю, как преобразовать наш существующий код JS. Мой подход (который вполне может быть ошибочным) состоит в том, чтобы сделать минимум, чтобы просто заставить его работать в TypeScript, а затем постепенно преобразовать его в соответствии с «лучшими практиками».

Кажется, я упал на первом барьере.....

У меня есть следующий TypeScript, использующий jQuery (в приложении ASP.NET .NET5).

interface MyInterface {
    prop1: string;
    prop2: number;
}

const something = {
    currentThing : MyInterface,

    init: (): void => {
        //
    }
};

$(something.init);

Итак, идея в том, что когда страница загружается, something.init будет выполняться. Это настроит такие вещи, как обработчики событий через селекторы jQuery и т. д. и т. д. Кажется, что вся эта часть работает нормально.

Однако...

В какой-то момент сработает обработчик событий, и я создам новый объект, который будет реализовывать MyInterface. Мне нужно будет сохранить это (установив его как значение свойства/поля currentThing), чтобы к нему можно было получить доступ для будущих событий.

Однако Typescript не любит строку currentActivity: MyInterface,, и я получаю сообщение об ошибке:

«MyInterface» относится только к типу, но здесь используется как значение.

Вы не можете назначать типы свойствам внутри литерала объекта. Вам нужно назначить тип для этого объекта something, например, как const something: { currentThing: MyInterface, init: () => void } = { /* ... */}. Также, вероятно, неплохо извлечь этот интерфейс.

VLAZ 10.12.2020 11:43
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
80
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я рекомендую вам ввести свой something объект, используя новый интерфейс, как :

interface MyInterface {
    prop1: string;
    prop2: number;
}

interface Something {
  currentThing: MyInterface;
  init: () => void;
}

const something: Something = {
    currentThing: {
      prop1: 'foo',
      prop2: 5,
    },

    init: (): void => {
        //
    },
};

console.info(something.init);
Ответ принят как подходящий

Объект следует структуре ключ-значение, Typescript понимает текущее определение объекта как

const something = {
    //    key         value
    currentThing : MyInterface,    
};

а поскольку MyInterface не является допустимым значением, будет выдана указанная ошибка.

Что вам нужно сделать в этом случае, так это определить типы для объекта something, введя его свойства следующим образом:

interface MyInterface {
    prop1: string;
    prop2: number;
}

interface SomethingInterface {
    currentThing : MyInterface;
    init: () => void
}

const currentThing = { prop1: 'aStringValue', prop2: 12345 };
const something: SomethingInterface = {
    currentThing,
    init: (): void => {
        //
    }
};

$(something.init);

Я попробовал вышеизложенное (что работает), но со следующей адаптацией. Я хотел бы услышать, считают ли мою адаптацию хорошей практикой или нет... Я изменил const currentThing = { prop1: 'aStringValue', prop2: 12345 }; на const currentThing: MyInterface = null;, так как не хотел создавать фиктивный объект. Я также не был уверен, должно ли это быть const... В функции init я мог установить его с помощью something.currentThing = { prop1: "abc", prop2: 12345 }; и получить позже.

DrGriff 10.12.2020 12:40

Думали ли вы использовать class? Например, вы можете заменить init() на constructor(), а затем вызвать $(new Something(currentThing)).

Claudio Busatto 10.12.2020 19:59

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

Пример:

interface MyInterface {
    prop1: string;
    prop2: number;
}

class Something implements MyInterface {

    public Something(public prop1: string, public prop2: number) {
    }

    init(): void {
    }
}

export const something = new Something('value1', 10);

$(something.init);

Другие вопросы по теме