Я прочитал объект JSON с удаленного сервера REST. Этот объект JSON имеет все свойства класса машинописного текста (в соответствии с дизайном). Как преобразовать полученный полученный объект JSON в тип var?
Я не хочу заполнять машинописный текст var (то есть иметь конструктор, который принимает этот объект JSON). Он большой, и копирование всего через подобъект по подобъекту и свойству по свойству займет много времени.
Обновление: однако вы можете привести его к интерфейсу машинописи!
json
typescript
Дэвид Тилен
источник
источник
Ответы:
Вы не можете просто преобразовать результат простого старого JavaScript из запроса Ajax в прототипный экземпляр класса JavaScript / TypeScript. Для этого существует ряд методов, которые обычно включают копирование данных. Если вы не создадите экземпляр класса, у него не будет никаких методов или свойств. Это останется простым объектом JavaScript.
Хотя, если бы вы имели дело только с данными, вы могли бы просто выполнить приведение к интерфейсу (поскольку это просто структура времени компиляции), для этого потребовалось бы использовать класс TypeScript, который использует экземпляр данных и выполняет операции с этими данными.
Некоторые примеры копирования данных:
По сути, вы бы просто:
источник
JSON.parse()
. И то, и другое еще нужно сделать, но синтаксически их можно объединить.Object.setPrototypeOf
У меня была та же проблема, и я нашел библиотеку, которая выполняет эту работу: https://github.com/pleerock/class-transformer .
Это работает так:
Он поддерживает вложенные дочерние элементы, но вы должны украсить члена вашего класса.
источник
@Type
хотя не забывайте свои аннотации). Этот ответ заслуживает большего доверия.В TypeScript вы можете сделать утверждение типа с помощью интерфейса и обобщенных типов, например, так:
Где ILocationMap описывает форму ваших данных. Преимущество этого метода в том, что ваш JSON может содержать больше свойств, но форма удовлетворяет условиям интерфейса.
Надеюсь, это поможет!
источник
Если вы используете ES6, попробуйте это:
Но , к сожалению, этот способ не будет работать на объекте гнезда .
источник
Object.create(MyClass.prototype)
обхода конструктора вообще.Я нашел очень интересную статью о приведении JSON к классу Typescript:
http://cloudmark.github.io/Json-Mapping/
Вы получите следующий код:
источник
TLDR: один лайнер
Подробный ответ
Я бы не стал рекомендовал подход Object.assign, поскольку он может ненадлежащим образом засорять ваш экземпляр класса нерелевантными свойствами (а также определенными замыканиями), которые не были объявлены внутри самого класса.
В классе, в который вы пытаетесь десериализоваться, я бы гарантировал, что все свойства, которые вы хотите десериализовать, определены (нуль, пустой массив и т. Д.). Определяя ваши свойства с начальными значениями, вы открываете их видимость при попытке перебрать членов класса для назначения значений (см. Метод десериализации ниже).
В приведенном выше примере я просто создал метод десериализации. В реальном примере я бы централизовал его в повторно используемом базовом классе или методе обслуживания.
Вот как использовать это в чем-то вроде http соответственно ...
Если tslint / ide жалуется на несовместимость типа аргумента, просто приведите аргумент к тому же типу, используя угловые скобки
<YourClassName>
, например:Если у вас есть члены класса определенного типа (иначе: экземпляр другого класса), вы можете привести их к типизированным экземплярам с помощью методов getter / setter.
Приведенный выше пример десериализует как acct, так и список задач в их соответствующие экземпляры классов.
источник
Предполагая, что json имеет те же свойства, что и ваш класс машинописи, вам не нужно копировать свойства Json в объект машинописи. Вам просто нужно создать свой объект Typescript, передавая данные json в конструктор.
В вашем обратном вызове ajax вы получаете компанию:
Для того, чтобы сделать эту работу:
1) Добавьте конструктор в свой класс Typescript, который принимает данные json в качестве параметра. В этом конструкторе вы расширяете свой объект json с помощью jQuery, например так:
$.extend( this, jsonData)
. $ .extend позволяет сохранить прототипы javascript при добавлении свойств объекта json.2) Обратите внимание, что вам придется сделать то же самое для связанных объектов. В случае Employees в примере вы также создаете конструктор, принимающий часть данных json для сотрудников. Вы вызываете $ .map для перевода сотрудников json в машинописные объекты Employee.
Это лучшее решение, которое я нашел при работе с классами Typescript и объектами json.
источник
Автоматически проверять, есть ли у объекта JSON, полученного с сервера, ожидаемые (читай, соответствуют) свойства интерфейса машинописного текста, пока нечем. Но вы можете использовать Определяемые пользователем Стражи Типа
Учитывая следующий интерфейс и глупый объект json (это мог быть любой тип):
Три возможных способа:
A. Утверждение типа или простое статическое приведение после переменной
B. Простое статическое приведение, перед переменной и между бриллиантами
C. Продвинутый динамический состав, вы сами проверяете структуру объекта
Вы можете поиграть с этим примером здесь
Обратите внимание, что здесь трудность заключается в написании
isMyInterface
функции. Я надеюсь, что TS добавит декоратор рано или поздно, чтобы экспортировать сложную типизацию во время выполнения и позволить среде выполнения проверять структуру объекта при необходимости. На данный момент вы можете использовать валидатор схемы json, цель которого примерно такая же, ИЛИ этот генератор функций проверки типа во время выполнения.источник
В моем случае это работает. Я использовал функции Object.assign (цель, источники ...) . Сначала создается правильный объект, затем копируются данные из объекта json в цель. Пример:
И более продвинутый пример использования. Пример использования массива.
источник
this.users[i] = new User(); Object.assign(this.users[i], users[i])
this.users[i] = Object.assign(new User(), users[i]);
Пока это не кастинг как таковой; Я нашел https://github.com/JohnWhiteTB/TypedJSON полезной альтернативой.
источник
Вы можете создать
interface
свой тип (SomeType
) и привести объект в него.источник
Если вам нужно привести ваш объект json к классу машинописного текста и иметь методы экземпляра, доступные в результирующем объекте, который вам нужно использовать
Object.setPrototypeOf
, как я сделал в фрагменте кода ниже:источник
Старый вопрос с в основном правильными, но не очень эффективными ответами. Вот что я предлагаю:
Создайте базовый класс, который содержит метод init () и статические методы приведения (для одного объекта и массива). Статические методы могут быть где угодно; версия с базовым классом и init () впоследствии позволяет легко расширяться.
Подобная механика (с assign () ) была упомянута в посте @ Adam111p. Просто еще один (более полный) способ сделать это. @Timothy Perez критически относится к assign () , но imho здесь вполне уместно.
Реализуйте производный (настоящий) класс:
Теперь мы можем привести объект, полученный из сервиса:
Вся иерархия SubjectArea объектов будет иметь правильный класс.
Вариант использования / пример; создайте сервис Angular (снова абстрактный базовый класс):
Использование становится очень простым; создать сервис Area:
Метод get () сервиса вернет Promise для массива, уже приведенного как SubjectArea объектам (вся иерархия)
Теперь скажите, у нас есть другой класс:
Создание службы, которая извлекает данные и приводит к правильному классу, так же просто, как:
источник
Используйте класс, расширенный из интерфейса.
Затем:
И лучше всего:
То, что становится контроллером DataInterface.
источник
https://jvilk.com/MakeTypes/
Вы можете использовать этот сайт для создания прокси для вас. он генерирует класс и может анализировать и проверять ваш входной объект JSON.
источник
В конце TS вы можете сделать так:
И чем пользователь, как это:
источник
Я столкнулся с аналогичной необходимостью. Я хотел что-то, что даст мне простое преобразование из / в JSON, которое приходит от вызова API REST в / из определенного определения класса. Решения, которые я нашел, были недостаточными или предназначались для того, чтобы переписать код моих классов и добавить аннотации или подобное.
Я хотел, чтобы что-то вроде GSON использовалось в Java для сериализации / десериализации классов в / из объектов JSON.
В связи с более поздней необходимостью, что конвертер будет работать и в JS, я закончил писать свой собственный пакет.
Это имеет, хотя, немного накладных расходов. Но при запуске его очень удобно добавлять и редактировать.
Вы инициализируете модуль с помощью:
Затем в своем коде вы используете инициализированный модуль, например:
или в JSON:
Используйте эту ссылку на пакет npm, а также подробное объяснение того, как работать с модулем: json-class-converter
Также обернул это для
углового использования в: angular-json-class-converter
источник
Передайте объект как есть конструктору класса; Нет соглашений или проверок
источник
Вы можете использовать этот пакет npm. https://www.npmjs.com/package/class-converter
Он прост в использовании, например:
источник
Лично я нахожу это ужасным, что машинопись не позволяет определению конечной точки указывать тип получаемого объекта. Похоже, что это действительно так, я бы сделал то же, что и с другими языками, и это то, что я отделил бы объект JSON от определения класса, и чтобы определение класса использовало объект JSON в качестве единственного члена данных ,
Я презираю шаблонный код, поэтому для меня это обычно вопрос достижения желаемого результата с наименьшим количеством кода при сохранении типа.
Рассмотрим следующие определения структуры объекта JSON - это будет то, что вы получите в конечной точке, это только определения структуры, а не методы.
Если мы думаем о вышеизложенном в объектно-ориентированных терминах, вышеупомянутые интерфейсы не являются классами, потому что они определяют только структуру данных. Класс в терминах ОО определяет данные и код, который работает с ними.
Итак, теперь мы определяем класс, который определяет данные и код, который работает с ними ...
И теперь мы можем просто передать любой объект, соответствующий структуре IPerson, и быть в пути ...
Таким же образом мы можем теперь обработать объект, полученный в вашей конечной точке, чем-то вроде ...
Это намного более эффективно и использует половину памяти для копирования данных, при этом значительно сокращая объем стандартного кода, который вы должны написать для каждого типа сущности. Он просто полагается на безопасность типов, обеспечиваемую TypeScript.
источник
Используйте «как» объявление:
источник
MyClass
.Это простой и действительно хороший вариант
И тогда у вас будет
источник
Я использовал эту библиотеку здесь: https://github.com/pleerock/class-transformer
Реализация:
Иногда вам нужно будет проанализировать значения JSON для plainToClass, чтобы понять, что это данные в формате JSON
источник
Я использую Angular 6 в веб-интерфейсе и Spring Boot-приложение в бэкэнде, которое возвращает объекты Java. Все, что мне нужно сделать, это определить аналогичный класс в угловом приложении, у которого есть совпадающие свойства, и тогда я могу принять объект «как» объект углового класса ( comp as Company в следующем примере).
См. Код переднего конца ниже, например. Дайте мне знать в комментариях, если что-то нуждается в большей ясности.
где company - это объект-сущность в весеннем загрузочном приложении, а также класс в Angular.
источник