Схема интерфейса Json - в сериализации отсутствуют некоторые поля

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

type SchemaDefinition<T> = {
  [K in keyof T]: {
    type: { new(): unknown } //
    required?: boolean
  }
}

class Schema<T> {
  constructor(public schema: SchemaDefinition<T>) {}

  validate(obj: T): boolean {
    for (const prop of Object.keys(this.schema) as (keyof T)[]) {
      if (!(obj[prop] instanceof this.schema[prop].type)) return false
      if (this.schema[prop].required && obj[prop] == null) return false
    }

    return true
  }
}

interface IUser {
  name: string;
  email: string;
}

Тут две схемы. 1. для контейнера, специфичного для языка программирования, который представляет собой интерфейс IUser 2. тот, который я хочу отправить на серверную часть, который состоит из объекта схемы, что-то вроде

new Schema<IUser>('users',
            {
                name: {type: Number, required: true},
                email: {type: String, required: true},
            });

теперь я пытаюсь сериализовать этот объект схемы в строку, используя JSON.stringify(), но type пропускается, как я могу его сериализовать или как я могу перевести это IUser в схему JSON наилучшим образом в TS.

Редактировать:

Я смог получить имя типа, выполнив что-то вроде этого

const schemaRepresentation = {};
schemaRepresentation['title'] = this._name;
schemaRepresentation['additionalProperties'] = false;
schemaRepresentation['additionalProperties'] = false;

const properties = {};

for (const schemaKey in this.schema) {
  properties[schemaKey.toString()] = this.schema[schemaKey].datatype.name;
}

schemaRepresentation['properties'] = properties

если в интерфейсе есть поле массива - как мне получить тип массива?

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
0
0
24
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам просто нужно использовать значения, которые можно сериализовать в JSON, потому что String и Number являются функциями и, следовательно, не сериализуемы.

Например, может быть, вы хотите проверить typeof obj[prop] для определенной строки.

type AllowedTypeNames = 'string' | 'number' | 'boolean'

type SchemaDefinition<T> = {
  [K in keyof T]: {
    type: AllowedTypeNames
    required?: boolean
  }
}

И validate теперь будет выглядеть так:

  validate(obj: T): boolean {
    for (const prop of Object.keys(this.schema) as (keyof T)[]) {
      if (typeof obj[prop] !== this.schema[prop].type) return false
      // ^ check if the typeof the obj[prop] matches the schema.

      if (this.schema[prop].required && obj[prop] == null) return false
      // ^ check if the typeof the obj[prop] is required and present.
    }

    return true
  }

Что сериализуется нормально:

const userSchema = new Schema<IUser>({
  name: { type: 'string', required: true },
  email: { type: 'string', required: true },
});

console.log(JSON.stringify(userSchema.schema))
// {"name":{"type":"string","required":true},"email":{"type":"string","required":true}}

Посмотреть игровую площадку

Спасибо, Алекс. Я смог получить тип, сделав что-то, о чем идет речь (отредактировано). ваш подход хорош, но он не сработает для меня, так как ограничивает тип. Теперь вопрос в том, как мне получить фактический тип массива. +1

user3833308 17.05.2022 22:36

Пожалуйста, дайте мне знать, если вы считаете, что это другой вопрос и заслуживает нового вопроса SO.

user3833308 17.05.2022 22:37

Это новый вопрос :) Также вы уверены, что не просто повторно реализуете json-schema.org?

Alex Wayne 17.05.2022 22:55

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

user3833308 17.05.2022 22:58

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