У меня есть серверное приложение, которое получает входные данные в виде объектов 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 есть такая же возможность, но я пока не пробовал.