npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@orzechowskid/eslint-plugin-typelint

v0.8.0

Published

type linting for Javascript with JSDoc

Downloads

6

Readme

Table of Contents

Why?

I like typed code, and I don't like the idea of introducing a new syntax and a new toolchain to support it in Javascript. This eslint plugin is an attempt to reconcile those two facts. It works by examining JSDoc comments attached to your variables and functions, to (attempt to) make sure you're not accidentally using the wrong datatype.

This plugin is not, and will never be, a complete replacement for TypeScript. But if all you want is to avoid some basic type-related footguns then it's probably good enough.

Example

/**
 * @param {boolean} myBool
 * @return {string}
 */
function booleanIsTrue(myBool) {
  return myBool ? "yes" : "no";
}

/** @type {number} */
const x = booleanIsTrue(true);
// eslint message:
// "can't assign type string to variable of type number"

/** @type {string} */
const y = booleanIsTrue(true);
// correctly-typed, so no eslint message! 🎉

const z = booleanIsTrue(false);
// also no eslint message, since `z` has no declared type 🤔 (you should fix that!)

Installation

this plugin requires eslint, so be sure to install that too if you're not already using it:

$ npm install --save-dev eslint @orzechowskid/eslint-plugin-typelint

it's highly recommended that you use eslint-plugin-jsdoc as well, to ensure your type definitions are well-formed:

$ npm install --save-dev eslint-plugin-jsdoc

Configuration

add one or more typelint rules to your eslint config file:

module.exports = {
  "plugins": [
    "jsdoc",
    "@orzechowskid/typelint"
  ],
  "parserOptions": {
    "ecmaFeatures": {
      "impliedStrict": true
    },
    "ecmaVersion": 8,
    "loc": true
  },
  "rules": {
    "@orzechowskid/typelint/assignment-types-must-match": [ "error" ]
  }
};

Available rules

assignment-types-must-match

Description

ensures that the types on the left-hand and right-hand sides of a statement match when initializing or assigning to a variable

Options

none

Examples

// does not pass - attempting to assign a number to a variable declared as a boolean

/** @type {boolean} */
const myBoolean = 123;


// does not pass - variable declared as a boolean but function's return value is a string

/** @type {boolean} */
const myBoolean = someFunctionReturningAString();


// does not pass - variable declared as boolean but actual runtime value is either boolean or undefined

/** @type {boolean} */
const myBoolean = someTest ? true : undefined;


// passes

/** @type {boolean} */
const myBoolean = someTest ? true : false;


// passes

/** @type {boolean} */
const myBoolean = someFunctionReturningABoolean();


// passes

/** @type {boolean|undefined} */
const myBoolean = someTest ? true : undefined;

function-args-length-must-match

Description

ensures that a function is always called with the number of parameters it expects.

Options

none

Examples

/**
 * @param {number} a
 * @param {number} b
 * @return {number}
 */
function myFunction(a, b) {
  return a ^ b;
}


// does not pass - function expects 2 arguments but was only given 1

const myNum = myFunction(10);


// does not pass - function expects 2 arguments but was given 3

const myNum = myFunction(10, 7, 12);


// passes

const myNum = myFunction(10, 7);

function-args-types-must-match

Description

ensures that a function's arguments match the types documented in its JSDoc block

Options

ignoreTrailingUndefineds

when set to true, this rule will not type-check any implicit parameters to the function call (where an 'implicit parameter' is what you get when e.g. calling myFun(x, y) with only one arg. the value y will be set to undefined). Default: false

Examples

/**
 * @param {string} name
 * @param {number} value
 * @return {string}
 */
 function appendValue(name, value) {
   return `${name}: ${value}`;
 }
 
 
 // does not pass - the first parameter should be a string
 
 const myStr = appendValue(123, 'Alice');
 
 
 // does not pass by default - the implicit second parameter is of type undefined
 
 const myStr = appendValue('Alice');
 
 
 // passes
 
 const myStr = appendValue('Alice', 123);
 
 
 // passes if the `ignoreTrailingUndefineds` option is set to true
 
 const myStr = appendValue('Alice');

function-return-type-must-match

Description

ensures that a function returns the value it says it will return in its documentation

Options

none

Examples

// does not pass - function says it returns a string but it actually returns a boolean

/**
 * @param {any} obj
 * @return {string}
 */
function toString(obj) {
  return !!obj.toString();
}


// does not pass - object literal does not match typedef

/**
 * @typedef {object} MyRecord
 * @property {string} name
 * @property {number} age
 */
 
 /**
  * @return {MyRecord}
  */
function getRecord() {
  return {
    name: 'Eric',
    age: 'none of your business'
  };
}


// does not pass - return value could either be a string or undefined

/**
 * @param {any} obj
 * @return {string}
 */
function toString(obj) {
  return obj ? obj.toString() : undefined;
}


// passes

/**
 * @param {any} obj
 * @return {string}
 */
function toString(obj) {
  return obj ? obj.toString() : 'does not exist';
}


// passes

/**
 * @return {Record}
 */
function getRecord() {
  return {
    name: 'Eric',
    age: 71
  };
}


// passes

/**
 * @param {any} obj
 * @return {string|undefined}
 */
function toString(obj) {
  return obj ? obj.toString() : undefined;
}

Bugs

probably lots! I'm not necessarily proud of this code!

you can file an issue here if something doesn't work the way you think it should, or even better: open a pull request here.

License

MIT