Implement Joi in Typescript - javascript

Simple joi validation snippet in javascript.It will simply return an error object when validation fails.
validate.js
const Joi =require("joi");
function validateObject (input) {
const schema = {
key: Joi.string().required(),
};
return Joi.validate(input, schema);
};
let {error} = validateObject({key:5})
console.log(error)
Now I am learning typescript and like to do the exact functionality in TS.I am aware that Joi is a javascript library but can we make use of it in Typescript.When exploring I came across some alternatives like https://github.com/joiful-ts/joiful.
I am curious to know if there is any straightforward approach using Joi directly in typescript. Or little bit of changes to make the Joi work exactly like in Javascript.
WHAT I TRIED
validate.ts
import * as Joi from "joi";
export const validateObject = (input: object) => {
const schema = {
home: Joi.string().required(),
};
return Joi.validate(input, schema);
};
validateObject({key:5})
While compiling, I got the error
Cannot find name 'Iterable'.
703 map(iterable: Iterable<[string | number | boolean | symbol,
symbol]> | { [key: string]: symbol }): this;
UPDATE
I have installed #types/joi as suggested in the answer but still the same error
I am basically looking for validating string,boolean,number,array and object keys as it can be done easily with Joi in Javascript

Please change your import
-const Joi =require("joi");
+import Joi from "joi";
And make sure you've installed the types by using
npm install --save-dev #types/joi

Type definitions for Joi exists: #types/joi or #types/hapi__joi (for joi version 17).
Add those to your package.json, and you should be able to use Joi with Typescript. Generally speaking you should not be downloading seperate libraries to make a package work in Typescript, some definitions should do

Try to use this code instead.
import * as Joi from "joi";
export const validateObject = (input: object) => {
const schema = Joi.object().keys({
home: Joi.string().required(),
});
return schema.validate(input);
};
validateObject({key:5})
I hope you will manage to make it work.

I doubt that import * as Joi from "joi" is going to give you much joy. You are importing all exported members with that.
Is there an individual export you are wanting? Use import { IndividualExport } from "joi"
Is there a default export you are wanting? Use import Joi from "joi"
Also is there a reason you are calling Joi in the second example but not the first?

Zod seems to be a popular Joi alternative for TypeScrip:
https://www.npmjs.com/package/zod

Related

Change JavaScript in TypeScript

I would like to translate this code into actual TypeScript. Could you help me there?
import mongoose, { Promise } from 'mongoose';
Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
db.user = require("./user.model");
db.role = require("./role.model");
db.ROLES = ["user", "admin", "moderator"];
export default db;
It would be great if you'd provide us with what you have tried and achieved so that it is easier to modify your code.
A way to do this would be to type this in a TypeScript file in an editor that provides linting for TypeScript like Visual Studio Code. Then check all the errors and fix them.

YAML validation using JSON schema

I am having a CI service that validates YAML files using JSON schema. The solution works by firstly converting the YAML to JSON using js-yaml and then by checking the schema using ajv
sample code:
import { load } from 'js-yaml';
import { default as Ajv } from 'ajv';
import schema from '../../schema.json';
const ajv = new Ajv({
strict: false
});
export const validate = (file: { content: string }) => {
const parsed = load(file.content) as unknown;
const valid = ajv.validate(schema, parsed);
if (!valid) throw new Error(ajv.errorsText());
}
I would like to extend this solution to report back with the error Line and Column.
Do you know if there is a solution for this out there already? My GoogleFu let me down this time. The closest I got is vscode XML plugin vscode YAML plugin which seems to be tightly coupled with VS code :(

Importing from validator in javascript

I want to use the validator for an express project. How do I import just two subsets of the packages directly?
Like:
import {isEmail, isEmpty} from 'validator';
or importing each on a separate line.
I just want to know if there is another option apart from import validator from 'validator'; as stated on the https://www.npmjs.com/package/validator
const isEmailValidator = require('validator').isEmail;
const isEmptyValidator = require('validator').isEmpty;
isEmailValidator('bla#bla.com');
Like this you mean? What you wrote should also be valid:
import {isEmail, isEmpty} from 'validator';
isEmail('bla#bla.com');
Edit for clarification: As you can see here https://github.com/chriso/validator.js/blob/master/src/index.js the library is exporting an object with each function. You can import everything import validator from 'validator' or you can use destructuring to get only a few properties.
const {isEmail, isEmpty} = require('validator');
This will not actually stop node from importing all of validator though. This just has node load the validator object that is returned from that modules export and then destructures isEmail and isEmpty out of the exported Object.
Maybe whenever ES6 modules become full supported you can use the regular import syntax. See node.js documentation: ECMAScript Modules.

react-create-app/flow-type doesn't work correctly

When i write functional components and describe prop types as flow it doesn't recognize that. Example below should throw an error because props.some isn't a string it is actually a number.
// #flow
import React from 'react'
import {compose, withProps} from 'recompose'
const
App = (props: {
some: string
}) => <div className='App'>{props.some}</div>
export default compose(
withProps({
some: 42
})
)(App) //Response => No Errors
In other cases such (e: string) => e; e(42); // => Error flow-type works fine.
My .flowconfig is only after flow init.
I think the issue here is getting the types for the recompose library. Without that, Flow has no way to know what the type of the wrapping component should be. Have you installed a libdef for recompose?
Installed flow-typed helped. And there is an article of how to install flow-type with recompose

React create constants file

How to create constants file like: key - value in ReactJs,
ACTION_INVALID = "This action is invalid!"
and to use that in other components
errorMsg = myConstClass.ACTION_INVALID;
I'm not entirely sure I got your question but if I did it should be quite simple:
From my understanding you just want to create a file with constants and use it in another file.
fileWithConstants.js:
export const ACTION_INVALID = "This action is invalid!"
export const CONSTANT_NUMBER_1 = 'hello I am a constant';
export const CONSTANT_NUMBER_2 = 'hello I am also a constant';
fileThatUsesConstants.js:
import * as myConstClass from 'path/to/fileWithConstants';
const errorMsg = myConstClass.ACTION_INVALID;
If you are using react you should have either webpack or packager (for react-native) so you should have babel which can translate your use of export and import to older js.
You can simply create an object for your constants:
const myConstClass = {
ACTION_INVALID: "This action is invalid!"
}
And then use it.
If you are bundling, you can export this object and then import for each component file.
Expanding on Monad's answer, for situations where you don't want to type myConstClass all the time:
fileWithConstants.js:
export const ACTION_INVALID = "This action is invalid!"
export const CONSTANT_NUMBER_1 = 'hello I am a constant';
export const CONSTANT_NUMBER_2 = 'hello I am also a constant';
fileThatUsesConstants.js:
import { ACTION_INVALID } from 'path/to/fileWithConstants';
const errorMsg = ACTION_INVALID;
(Also, if Monad's way works better for you, I believe the convention is for 'MyConstClass' to start with a capital letter, since it's acting like a class in code.)
One way to do that (not so different from other answers though) is to create a bare constants.js file and add your constants there.
module.exports = Object.freeze({
ACTION_INVALID: 'This action is invalid',
ACTION_VALID: 'Some other action',
});
Then you can import it
import ConstantsList from './constants';
and use
console.log(ConstantsList.ACTION_INVALID)
As the name suggests, Object.freeze() freezes objects and stops anyone from changing the values. Please note: if the values are objects themselves they are changeable (unless they are also frozen)
In nodejs enviroment, when using absolute path, there already is deprecated "constants" and it may conflict with yours, so it's better to create either a folder and put your constants there or create a file with name consts.
Your constants should look like that, use Object.freeze so that constants are never changed by a side effect. You should use Object.freeze for every object.
export const ACTION_INVALID = "This action is invalid!"
export const FILE_TYPES = Object.freeze({
IMAGE: Object.freeze(["JPEG", "PNG"]),
VIDEO: Object.freeze(["MP4", "M4V", "MOV", "3GP", "3G2", "WMV", "ASF", "AVI", "FLV", "MKV", "WEBM"])
})

Categories

Resources