{"id":16736189,"url":"https://github.com/flexdinesh/typy","last_synced_at":"2025-04-04T11:15:27.531Z","repository":{"id":44463021,"uuid":"119795779","full_name":"flexdinesh/typy","owner":"flexdinesh","description":"Minimal JavaScript type checking library","archived":false,"fork":false,"pushed_at":"2021-05-10T18:02:32.000Z","size":616,"stargazers_count":227,"open_issues_count":15,"forks_count":25,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-05-27T22:16:48.232Z","etag":null,"topics":["javascript","javascript-library","js","npm-package","object","type-check"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flexdinesh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-01T06:50:46.000Z","updated_at":"2024-04-07T07:43:10.000Z","dependencies_parsed_at":"2022-07-28T23:18:44.164Z","dependency_job_id":null,"html_url":"https://github.com/flexdinesh/typy","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flexdinesh%2Ftypy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flexdinesh%2Ftypy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flexdinesh%2Ftypy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flexdinesh%2Ftypy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flexdinesh","download_url":"https://codeload.github.com/flexdinesh/typy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166169,"owners_count":20894654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","javascript-library","js","npm-package","object","type-check"],"created_at":"2024-10-13T00:08:36.421Z","updated_at":"2025-04-04T11:15:27.506Z","avatar_url":"https://github.com/flexdinesh.png","language":"JavaScript","readme":"# Typy\n\n[![Build Status](https://travis-ci.org/flexdinesh/typy.svg?branch=master)](https://travis-ci.org/flexdinesh/typy)\n[![dependencies Status](https://david-dm.org/flexdinesh/typy/status.svg)](https://david-dm.org/flexdinesh/typy)\n[![npm version](https://badge.fury.io/js/typy.svg)](https://www.npmjs.com/package/typy)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Gitter](https://badges.gitter.im/flexdinesh/typy.svg)](https://gitter.im/flexdinesh/typy?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\nType checking library for JavaScript with a _'sweeter'_ syntax.\n\n`t('foo').isString // =\u003e true`\n\n## New in version 3 🔥\n\n- [Schema Validation](#isvalid-schema-validation)\n- [Custom Types](#addcustomtypes-custom-types)\n\nVersion **3.0.0** introduces **BREAKING** changes (for node.js CommonJS style imports only).\n\n```js\n// Before v3.0.0, `t` function was imported as\nconst t = require('typy');\n\n//From v3.0.0, `t` function should be imported as\nconst { t } = require('typy');\n\n// Note: This version does not affect previous ES6 style imports._\nimport t, { Schema, addCustomTypes } from 'typy'; // this will still work\nimport { t, Schema, addCustomTypes } from 'typy'; // this will also work\n```\n\n## Why? [![start with why](https://img.shields.io/badge/start%20with-why%3F-brightgreen.svg?style=flat)](http://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action)\n\nThere are a hundred other type checking libraries out there. But **Typy** is built with three core behavioral aspects.\n\n1. No surprises. **Typy** will never throw, no matter what the input is.\n2. Object check will only look for **{ }** rather than JavaScript's native behavior of considering everything as objects such as arrays, functions, null, etc.\n3. _Thought Driven Development_. Code should exactly mimic your thoughts on the logic rather than writing extra code just because that's how JavaScript works. `t(obj).isDefined // =\u003e true`\n4. Custom type validation and schema validation.\n\n## Install\n\n```\n$ npm install --save typy\n```\n\n## Usage\n\n```js\nimport t from 'typy'; // ES6 style import\n// var t = require('typy'); // CommonJS style import (version \u003c 3)\n// var t = require('typy').default; // CommonJS style import (version \u003e= 3)\n\nif (t('hello').isString) { // =\u003e true\n  console.log('Input is a String!')\n} else {\n  console.log('Input is not a String!')\n}\n\n// More examples\nt('22').isNumber // =\u003e false\nt('22').isString // =\u003e true\nt({}).isObject // =\u003e true\nt([]).isArray // =\u003e true\nt([]).isObject // =\u003e false\n\nconst sym = Symbol('typyIsAwesome');\nt(sym).isSymbol // =\u003e true\n\n// obj.goodKey.nestedKey = 'helloworld'\nt(obj, 'goodKey.nestedKey').isDefined // =\u003e true\nt(obj, 'badKey.nestedKey').isDefined // =\u003e false\n// Typy won't throw undefined error for badKey.nestedKey\n\n// to check if obj.goodKey.nestedKey is a string\nt(obj, 'goodKey.nestedKey').isString // =\u003e true\nt(obj, 'badKey.nestedKey').isString // =\u003e false\n\nconst deepObj = {\n  nestedKey: {\n    goodKey: 'hello',\n    superNestedKey: {}\n  }\n};\n// safely return the value from a nested key in an object\nconst myObj = t(deepObj, 'nestedKey.goodKey').safeObject; // =\u003e 'hello'\n// Typy won't throw undefined error for badKey.goodKey\n// instead the return value will be undefined\nconst myObj = t(deepObj, 'badKey.goodKey').safeObject; // =\u003e undefined\n```\n\n## API\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n  - [t(input, optionalObjectPath)](#tinput-optionalobjectpath)\n  - [isDefined](#isdefined)\n  - [isUndefined](#isundefined)\n  - [isNull](#isnull)\n  - [isNullOrUndefined](#isnullorundefined)\n  - [isBoolean](#isboolean)\n  - [isTrue](#istrue)\n  - [isFalse](#isfalse)\n  - [isTruthy](#istruthy)\n  - [isFalsy](#isfalsy)\n  - [isObject](#isobject)\n  - [isEmptyObject](#isemptyobject)\n  - [isString](#isstring)\n  - [isEmptyString](#isemptystring)\n  - [isNumber](#isnumber)\n  - [isArray](#isarray)\n  - [isEmptyArray](#isemptyarray)\n  - [isFunction](#isfunction)\n  - [isDate](#isdate)\n  - [isSymbol](#issymbol)\n  - [safeObject](#safeobject)\n  - [safeObjectOrEmpty](#safeobjectorempty)\n  - [safeString](#safestring)\n  - [safeNumber](#safenumber)\n  - [safeBoolean](#safeboolean)\n  - [safeFunction](#safefunction)\n  - [safeArray](#safearray)\n  - [isValid (Schema Validation)](#isvalid-schema-validation)\n  - [addCustomTypes (Custom Types)](#addcustomtypes-custom-types)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n#### t(input, optionalObjectPath)\n\nPass in your input to the t() method and **Typy** will take care of everything\n\n```js\n// you can pass any type of input\n// Number, String, Object, null, undefined, Array, anything\nt('str')\nt(22)\nt({foo: 'fooooo', bar: 'barooo'})\nt([2, 'three', 'hey'])\n\nconst obj = {\n  goodKey: {\n    nestedKey: 'hello world'\n  }\n}\n// To pass nested path of an object\n// Ex. obj.goodKey.nestedKey\n// You have to pass the path as string in the second param\nt(obj, 'goodKey.nestedKey')\nt(obj, 'badKey.nestedKey')\n// this is because if you pass t(obj.badKey.nestedKey),\n// you will get undefined exception\n// because that is how javascript is designed\n// to overcome that we need to pass the sub key as a string to Typy\n```\n\n#### isDefined\n\nReturns _true_ if the input is defined.\n\n```js\nconst obj = {\n  goodKey: 'hello'\n}\n\nt(obj.goodKey).isDefined // =\u003e true\nt(obj.badKey).isDefined // =\u003e false\n```\n\n#### isUndefined\n\nReturns _true_ if the input is undefined.\n\n```js\nconst obj = {\n  goodKey: 'hello'\n}\n\nt(obj.goodKey).isUndefined // =\u003e false\nt(obj.badKey).isUndefined // =\u003e true\n```\n\n#### isNull\n\nReturns _true_ if the input is null.\n\n```js\nconst obj = {\n  foo: null\n}\n\nt(obj.foo).isNull // =\u003e true\n```\n\n#### isNullOrUndefined\n\nReturns _true_ if the input is null or undefined.\n\n```js\nconst obj = {\n  foo: null\n}\n\nt(obj.foo).isNullOrUndefined // =\u003e true\nt(obj.bar).isNullOrUndefined // =\u003e true\n```\n\n#### isBoolean\n\nReturns _true_ if the input is either `true` or `false`.\n\n```js\nt(true).isBoolean // =\u003e true\nt(false).isBoolean // =\u003e true\n```\n\n#### isTrue\n\nReturns _true_ if the input is Boolean `true`.\n\n```js\nt(true).isTrue // =\u003e true\nt(false).isTrue // =\u003e false\n```\n\n#### isFalse\n\nReturns _true_ if the input is Boolean `false`.\n\n```js\nt(true).isFalse // =\u003e false\nt(false).isFalse // =\u003e true\n```\n\n#### isTruthy\n\nReturns _true_ if the input is considered _truthy_.\n\nIn JavaScript anything other than `false`, `0`, `''`, `\"\"`, `null`, `undefined` and `NaN` is considered _truthy_.\n\n```js\nt('Typy is amazing =)').isTruthy // =\u003e true\nt({}).isTruthy // =\u003e true\nt(22).isTruthy // =\u003e true\nt([1, 'two']).isTruthy // =\u003e true\n```\n\n#### isFalsy\n\nReturns _true_ if the input is considered _falsy_.\n\nIn JavaScript any of these values `false`, `0`, `''`, `\"\"`, `null`, `undefined` and `NaN` are considered _falsy_.\n\n```js\nt(0).isFalsy // =\u003e true\nt(null).isFalsy // =\u003e true\nt(undefined).isFalsy // =\u003e true\nt(false).isFalsy // =\u003e true\n```\n\n\n#### isObject\n\nReturns _true_ if the input is an object.\n\n```js\nconst obj = {\n  foo: null\n}\n\nt(obj).isObject // =\u003e true\nt({}).isObject // =\u003e true\n```\n\n_Note: Only { } objects will return this as true as opposed to javascript definition of Object which includes Arrays, Functions, anything and everything related to prototype. This is an intentional behavior as we don't want arrays to return true for isObject._\n\n#### isEmptyObject\n\nReturns _true_ if the input is an empty object, _aka_ object without any keys.\n\n```js\nconst obj = {\n  foo: 'hello there',\n  bar: {}\n}\n\nt(obj.bar).isEmptyObject // =\u003e true\nt({}).isEmptyObject // =\u003e true\nt(obj).isEmptyObject // =\u003e false\n```\n\n#### isString\n\nReturns _true_ if the input is a string.\n\n```js\nconst obj = {\n  foo: 'typy is awesome =)',\n}\nt(obj.foo).isString // =\u003e true\nt('').isString // =\u003e true\nt(22).isString // =\u003e false\nt(null).isString // =\u003e false\n```\n\n#### isEmptyString\n\nReturns _true_ if the input is an empty string.\n\n```js\nt('').isEmptyString // =\u003e true\nt('typy is so great').isEmptyString // =\u003e false\n```\n\n#### isNumber\n\nReturns _true_ if the input is a number.\n\n```js\nt(22).isNumber // =\u003e true\nt('i am a string').isNumber // =\u003e false\nt({}).isNumber // =\u003e false\n```\n\n#### isArray\n\nReturns _true_ if the input is an array.\n\n```js\nt([]).isArray // =\u003e true\nt([1, 2, 'typy']).isArray // =\u003e true\nt({}).isArray // =\u003e false\n```\n\n#### isEmptyArray\n\nReturns _true_ if the input is an empty array.\n\n```js\nt([]).isEmptyArray // =\u003e true\nt([1, 2, 'typy']).isEmptyArray // =\u003e false\n```\n\n#### isFunction\n\nReturns _true_ if the input is a function.\n\n```js\nconst func = () =\u003e {};\nt(func).isFunction // =\u003e true\nt({}).isFunction // =\u003e false\n```\n\n#### isDate\n\nReturns _true_ if the input is a javascript's date object.\n\n```js\nconst date = new Date();\nt(date).isDate // =\u003e true\nt({}).isDate // =\u003e false\n```\n\n#### isSymbol\n\nReturns _true_ if the input is a javascript's Symbol.\n\n```js\nconst mySym = Symbol(123);\nconst anotherSymbol = Symbol('typyIsAwesome');\n\nt(mySym).isSymbol // =\u003e true;\nt(Object(anotherSymbol)).isSymbol  // =\u003e true;\n\nt({}).isSymbol // =\u003e false\nt([]).isSymbol // =\u003e false\nt(null).isSymbol // =\u003e false\n```\n\n#### safeObject\n\nSafely returns the value from a nested object path without throwing any error.\n\n```js\nconst deepObj = {\n  nestedKey: {\n    goodKey: 'hello',\n    superNestedKey: {}\n  }\n};\n// Typy can safely return the value from a nested key in an object\nconst myObj = t(deepObj, 'nestedKey.goodKey').safeObject; // =\u003e 'hello'\n// Typy won't throw if the key at any level is not found\n// instead will return undefined\nconst myObj = t(deepObj, 'badKey.goodKey').safeObject; // =\u003e undefined\n\nconst anotherDeepObj = {\n  nestedArray: [{\n    goodKey: 'hello one',\n    superNestedKey: {}\n  }, {\n    goodKey: 'hello two',\n    superNestedKey: {\n      superGoodKey: 'typy is great :)'\n    }\n  }]\n};\n// Typy can safely return the value even from a nested key in a nested array\nconst myObj = t(anotherDeepObj, 'nestedArray[1].superNestedKey.superGoodKey').safeObject; // =\u003e 'typy is great :)'\n```\n\n#### safeObjectOrEmpty\n\nSafely returns the value from a nested object path if the path exists\nor returns an empty object if the.\n\n```js\nconst deepObj = {\n  nestedKey: {\n    goodKey: 'hello',\n    superNestedKey: {}\n  }\n};\n// Typy can safely return the value from a nested key in an object\nconst myObj = t(deepObj, 'nestedKey.goodKey').safeObjectOrEmpty; // =\u003e 'hello'\n// Typy won't throw if the key at any level is not found\n// instead will return an empty object\nconst myObj = t(deepObj, 'badKey.goodKey').safeObjectOrEmpty; // =\u003e {}\n\nconst anotherDeepObj = {\n  nestedArray: [{\n    goodKey: 'hello one',\n    superNestedKey: {}\n  }, {\n    goodKey: 'hello two',\n    superNestedKey: {\n      superGoodKey: 'typy is great :)'\n    }\n  }]\n};\n// Typy can safely return the value even from a nested key in a nested array\nconst myObj = t(anotherDeepObj, 'nestedArray[1].superNestedKey.superGoodKey').safeObjectOrEmpty; // =\u003e 'typy is great :)'\n```\n\n#### safeString\n\nReturns the string value if the input type is string or will return an empty string `''`.\n\n```js\nconst str = t('typy is safe').safeString; // =\u003e 'typy is safe'\nconst str = t(null).safeString; // =\u003e ''\nconst str = t(undefined).safeString; // =\u003e ''\nconst str = t(22).safeString; // =\u003e ''\n```\n\n#### safeNumber\n\nReturns the number if the input type is Number or will return `0`.\n\n```js\nconst num = t(22).safeNumber; // =\u003e 22\nconst num = t('22').safeNumber; // =\u003e 0\nconst num = t(undefined).safeNumber; // =\u003e 0\nconst num = t(null).safeNumber; // =\u003e 0\n```\n\n#### safeBoolean\n\nReturns the boolean if the input type is Boolean or will return `false`.\n\n```js\nconst bool = t(true).safeBoolean; // =\u003e true\nconst bool = t(false).safeBoolean; // =\u003e false\nconst bool = t('22').safeBoolean; // =\u003e false\nconst bool = t(undefined).safeBoolean; // =\u003e false\nconst bool = t(22).safeBoolean; // =\u003e false\n```\n\n#### safeFunction\n\nReturns the function if the input type is function or will return an empty function `() =\u003e {}`.\n\n```js\nconst helloFunc = () =\u003e { return 'Hello World!' }\nconst func = t(helloFunc).safeFunction; // =\u003e helloFunc reference\nconst func = t('I am a string').safeFunction; // =\u003e empty function () =\u003e {}\nconst func = t(undefined).safeFunction; // =\u003e empty function () =\u003e {}\nconst func = t(null).safeFunction; // =\u003e empty function () =\u003e {}\n```\n\n#### safeArray\n\nSafely returns the value from a nested object path or an empty array. If the path specified exists but is not an array, returns an array containing the value of the specified path.\n\n```js\nconst deepObj = {\n  nestedKey: [\n    {\n      goodKey: ['hello'],\n      numberKey: 10,\n      superNestedKey: {}\n    },\n  ]\n};\n// Typy can safely return the value from a nested key in an object or an array\nconst myObj = t(deepObj, 'nestedKey').safeArray; // =\u003e [ { goodKey: ['hello'], numberKey: 10, superNestedKey: {} } ]\nconst myObj = t(deepObj, 'nestedKey[0].goodKey').safeArray; // =\u003e ['hello']\n// Typy can wrap a value or object inside an array\nconst myObj = t(deepObj, 'nestedKey[0].numberKey').safeArray; // =\u003e [ 10 ]\nconst myObj = t(deepObj, 'nestedKey[0].superNestedKey').safeArray; // =\u003e [ {} ]\n// Typy won't throw if the key at any level is not found\n// instead will return an empty array\nconst myObj = t(deepObj, 'nestedKey[1]').safeArray; // =\u003e []\nconst myObj = t(deepObj, 'badKey.goodKey').safeArray; // =\u003e []\n```\n\n#### isValid (Schema Validation)\n\n`isValid` is used to check and validate the schema of an object. It returns `true` if the schema of the object matches the schema passed or `false` if the schema doesn't match.\n\n```js\nimport t, { Schema } from 'typy';\n\nconst superheroSchema = {\n  name: Schema.String,\n  age: Schema.Number,\n  appearances: [\n    {\n      title: Schema.String,\n      alias: Schema.String,\n    }\n  ],\n  lastSeen: Schema.Date\n};\nconst batmanObject = {\n  name: 'Batman',\n  age: 45,\n  isAlive: true,\n  appearances: [\n    {\n      title: 'The Dark Knight',\n      alias: 'Bruce',\n    }\n  ],\n  lastSeen: new Date(14894561568)\n};\nconst isSchemaValid = t(batmanObject, superheroSchema).isValid; // true\n\nconst simpleSchema = {\n  name: Schema.String,\n  arr: Schema.Array\n};\nconst obj = {\n  name: 'Jack',\n  arr: [1, 2, 3]\n};\nconst isSchemaValid = t(obj, simpleSchema).isValid; // true\n```\n\nThe following **Schema types** are available in typy.\n\n- Number\n- String\n- Array\n- Boolean\n- Null\n- Undefined\n- Function\n- Date\n\n#### addCustomTypes (Custom Types)\n\n`addCustomTypes` is used to pass custom validators to **Typy**. It can be used to validate any ipnut for custom types, like this `t(input).isMyCustomType`.\n\nYou will have to add custom types only once in the project (preferabby in entry file. ex. `index.js`)\n\nEntry file (Ex. `index.js`)\n\n```js\nimport t, { addCustomTypes } from 'typy';\n\naddCustomTypes({\n  isPhone: (input) =\u003e (t(input).isNumber \u0026\u0026 /^\\d{10}$/g.test(String(input))), // has 10 digits\n  isAddress: (input) =\u003e (t(input).isString \u0026\u0026 input.toUpperCase().includes('STREET')) // includes 'street' in input\n});\n\n```\n\nAnywhere in the project\n\n```js\nimport t from 'typy';\n\nconst isThePhoneNumberValid = t(9892389239).isPhone; // =\u003e true\nconst isThePhoneNumberValid = t('abcdefg').isPhone; // =\u003e false\n\nconst isTheAddressValid = t('10 Downing Street').isAddress; // =\u003e true\nconst isTheAddressValid = t('I like cats 🐈').isAddress; // =\u003e false\n\n```\n\n## Contributors\n\nThanks goes to these amazing people 🎉\n\n| [\u003cimg src=\"https://avatars3.githubusercontent.com/u/5777880?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eDinesh Pandiyan\u003c/b\u003e\u003c/sub\u003e](https://github.com/flexdinesh)\u003cbr /\u003e | [\u003cimg src=\"https://avatars0.githubusercontent.com/u/6686039?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eOzair Patel\u003c/b\u003e\u003c/sub\u003e](https://github.com/OzairP)\u003cbr /\u003e | [\u003cimg src=\"https://avatars0.githubusercontent.com/u/23170622?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAneerudh\u003c/b\u003e\u003c/sub\u003e](https://github.com/Aneedroid)\u003cbr /\u003e | [\u003cimg src=\"https://avatars1.githubusercontent.com/u/13482258?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRuphaa Ganesh\u003c/b\u003e\u003c/sub\u003e](https://github.com/ruphaa)\u003cbr /\u003e | [\u003cimg src=\"https://avatars0.githubusercontent.com/u/4320434?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eQuentin Jadeau\u003c/b\u003e\u003c/sub\u003e](https://github.com/jadok)\u003cbr /\u003e | [\u003cimg src=\"https://avatars3.githubusercontent.com/u/416559?s=400\u0026v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003edan\u003c/b\u003e\u003c/sub\u003e](https://github.com/danthewolfe)\u003cbr /\u003e\n| :---: | :---: | :---: | :---: | :---: | :---: |\n| [\u003cimg src=\"https://avatars2.githubusercontent.com/u/13327?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRobert Schadek\u003c/b\u003e\u003c/sub\u003e](https://github.com/burner)\u003cbr /\u003e | [\u003cimg src=\"https://avatars0.githubusercontent.com/u/43963628?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMichael Kirkpatrick\u003c/b\u003e\u003c/sub\u003e](https://github.com/mlkirkpatrick)\u003cbr /\u003e | [\u003cimg src=\"https://avatars1.githubusercontent.com/u/13729562?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAna Liza Pandac\u003c/b\u003e\u003c/sub\u003e](https://github.com/analizapandac)\u003cbr /\u003e | [\u003cimg src=\"https://avatars1.githubusercontent.com/u/49582824?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAbdul Rehman\u003c/b\u003e\u003c/sub\u003e](https://github.com/rehman-00001)\u003cbr /\u003e | [\u003cimg src=\"https://avatars3.githubusercontent.com/u/13280256?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003elaevilgenius\u003c/b\u003e\u003c/sub\u003e](https://github.com/laevilgenius)\u003cbr /\u003e \n\n## License\n\nMIT © Dinesh Pandiyan\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflexdinesh%2Ftypy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflexdinesh%2Ftypy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflexdinesh%2Ftypy/lists"}