Проверка времени выполнения объекта Typescript с изюминкой

У меня есть серверное приложение, которое получает входные данные в виде объектов javascript. Мне нужно проверить, соответствуют ли эти данные таким требованиям, как:

  • он имеет обязательные поля, определенные интерфейсом
  • эти поля являются определенными типами
  • объект имеет только перечисленные поля, больше ничего

Я нашел 2 библиотеки, которые очень полезны для целей:

Библиотека типов запуска и io-ts

Например, используя типы выполнения, я могу создавать типы времени выполнения:

const PropSchema = Record({
    uid: String,
    name: String,
    timestamp: Number
});

И я могу создать статический тип из PropSchema:

type PropSchemaInterface = Static<typeof PropSchema>;

С этого момента я могу использовать его, как если бы это был интерфейс, typescript предупредит, если объект недействителен:

let props: PropSchemaInterface = { // this is invalid, because name is not a string
    uid: "31293-a7aa216982678",
    name: 4,
    timestamp: (new Date()).valueOf()
}

и проверьте, соответствует ли объект PropSchema:

PropSchema.check(props); // returns true

но

PropSchema.check({
    uid: "12"
});

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

PropsSchema.check({
    uid: "123-123123123",
    name: "John Snow",
    timestamp: 123123123,
    someKey: "somevalue"
});

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

Есть ли способ проверять объекты так, как я хочу? Runtypes – действительно полезная библиотека, так как она может выполнять проверку как во время выполнения, так и время компиляции. используя один и тот же дескриптор (PropSchema), и мне не нужно определять его дважды, но я не мог понять, как проверить наличие недопустимых членов объекта. У IO-TS есть такая же возможность, но я пока не пробовал.


person zak    schedule 11.05.2020    source источник
comment
Вы спрашиваете, какие библиотеки использовать, или хотите написать код для этого самостоятельно? В любом случае я рекомендую вам предоставить минимальный воспроизводимый пример, который либо не имеет сторонних зависимостей, таких как io- ts или runtypes, либо такие зависимости уже настроены в веб-IDE, на которую вы можете связать нас. Сейчас у меня слишком много работы, чтобы попытаться настроить это самостоятельно, поиграть с ним и внести конкретные предложения.   -  person jcalz    schedule 12.05.2020
comment
Согласен, пожалуйста, измените свой вопрос и сделайте его конкретным для типов запуска, я только что создал тег, если вам нужно. Вопрос типа «эта библиотека лучше, чем эта другая библиотека?» не следует спрашивать в stackoverflow. Пожалуйста, ознакомьтесь с рекомендациями, если хотите.   -  person Ronan Quillevere    schedule 01.10.2020
comment
я думал, что вопрос ясен: есть ли какая-нибудь библиотека, которая может выполнять проверку во время выполнения И способность фильтровать объект, имеющий несуществующие члены?   -  person zak    schedule 16.10.2020


Ответы (1)


Автор runtypes дает отличное объяснение того, почему посторонние типы разрешены, а точные типы в настоящее время не поддерживаются в его ответ на этот вопрос.

Если вы дочитали до конца этой проблемы (на момент написания этого 12 января 2021 г.), вы увидите, что ожидается PR, чтобы добавить это в качестве функции. Как только эта функция будет добавлена, ее использование решит вашу проблему и станет лучшим решением.

Тем временем, если бы я был на вашем месте, я бы добавил второй шаг проверки ваших объектов, который вручную перебирал бы ваши объекты и проверял, что там нет посторонних реквизитов. Это боль, но единственный краткосрочный обходной путь, о котором я могу думать, пока этот PR не будет объединен.

person Guy    schedule 12.01.2021
comment
Спасибо за ответ, именно так я и сделал. Я прекрасно понимаю, почему Runtypes не проверяет поля строго, но эта функция крайне необходима, и я действительно думаю, что не только мне. - person zak; 04.02.2021