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 🙏

© 2026 – Pkg Stats / Ryan Hefner

eslint-ts-avoid-as

v3.0.2

Published

ESLint rule to avoid `as` in cases where it seems unnecessary or wrong

Downloads

20

Readme

eslint-ts-avoid-as

npm version License: ISC

An ESLint plugin that helps you write safer TypeScript code by discouraging the use of as type assertions on literal values.

🎯 What does it do?

This ESLint rule identifies cases where you're using TypeScript's as type assertion on literal values (objects, arrays, strings, numbers, etc.) and suggests using the safer satisfies operator instead.

Why use satisfies instead of as?

The satisfies operator (introduced in TypeScript 4.9) is safer than as because:

  • Type checking: satisfies validates that your value actually matches the type, catching errors at compile time
  • Inference preservation: Your value keeps its specific inferred type (e.g., "red" stays as "red" instead of being widened to string)
  • Type assertions with as: Can force incompatible types, potentially hiding bugs

Example

❌ Bad (using as):

interface Config {
  name: string;
  value: number;
}

// This compiles but loses type information
const config = { name: "test", value: 42 } as Config;

// Dangerous: TypeScript won't catch this error!
const broken = { name: "test", wrongProp: true } as Config;

✅ Good (using satisfies):

interface Config {
  name: string;
  value: number;
}

// This validates the type AND preserves inference
const config = { name: "test", value: 42 } satisfies Config;

// TypeScript catches this error at compile time! 🎉
const broken = { name: "test", wrongProp: true } satisfies Config;
//    ^^^^^^ Error: Object literal may only specify known properties

📦 Installation

npm install --save-dev eslint-ts-avoid-as

Peer Dependencies:

  • eslint >= 8.0.0
  • @typescript-eslint/parser >= 8.0.0
  • typescript >= 5.0.0

🚀 Usage

1. Configure ESLint

Add the plugin to your ESLint configuration:

Using ESM (eslint.config.js):

import tsAvoidAs from 'eslint-ts-avoid-as';

export default [
  {
    plugins: {
      'ts-avoid-as': tsAvoidAs,
    },
    rules: {
      'ts-avoid-as/use-satisfies-for-literals': 'warn',
      'ts-avoid-as/literal-type-mismatch': 'error',
    },
  },
];

Using CommonJS (.eslintrc.js):

module.exports = {
  plugins: ['ts-avoid-as'],
  rules: {
    'ts-avoid-as/use-satisfies-for-literals': 'warn',
    'ts-avoid-as/literal-type-mismatch': 'error',
  },
};

Using JSON (.eslintrc.json):

{
  "plugins": ["ts-avoid-as"],
  "rules": {
    "ts-avoid-as/use-satisfies-for-literals": "warn",
    "ts-avoid-as/literal-type-mismatch": "error"
  }
}

2. Configure TypeScript Parser

This plugin requires type information, so make sure your ESLint config uses @typescript-eslint/parser:

Using ESM:

import tsParser from '@typescript-eslint/parser';
import tsAvoidAs from 'eslint-ts-avoid-as';

export default [
  {
    languageOptions: {
      parser: tsParser,
      parserOptions: {
        project: './tsconfig.json',
      },
    },
    plugins: {
      'ts-avoid-as': tsAvoidAs,
    },
    rules: {
      'ts-avoid-as/use-satisfies-for-literals': 'warn',
      'ts-avoid-as/literal-type-mismatch': 'error',
    },
  },
];

Using CommonJS:

module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: './tsconfig.json',
  },
  plugins: ['ts-avoid-as'],
  rules: {
    'ts-avoid-as/use-satisfies-for-literals': 'warn',
    'ts-avoid-as/literal-type-mismatch': 'error',
  },
};

📋 Rules

This plugin provides two separate rules that can be configured independently:

ts-avoid-as/use-satisfies-for-literals (Recommended: warn)

This rule warns when you use as on literal values with compatible types and provides an auto-fix to replace as with satisfies.

Why separate this rule? Using satisfies instead of as preserves type inference while still checking type compatibility. This is usually a safe change that improves type safety without breaking your code.

ts-avoid-as/literal-type-mismatch (Recommended: error)

This rule reports an error when you try to assert a literal value to an incompatible type using as. No auto-fix is provided because the code is likely incorrect and needs manual review.

Why separate this rule? Type mismatches are usually bugs that need immediate attention. Separating this allows you to treat them as errors while treating the safer satisfies suggestions as warnings.

📋 Rule Details

1. use-satisfies-for-literals: Compatible type assertions

When you use as on a literal value with a compatible type, this rule suggests using satisfies instead and provides an automatic fix.

Examples of incorrect code:

// ❌ Object literals
const obj = { x: 1, y: 2 } as Point;

// ❌ Array literals
const arr = [1, 2, 3] as number[];

// ❌ String literals
const str = "hello" as string;

// ❌ Number literals
const num = 42 as number;

// ❌ Boolean literals
const flag = true as boolean;

Examples of correct code:

// ✅ Using satisfies
const obj = { x: 1, y: 2 } satisfies Point;
const arr = [1, 2, 3] satisfies number[];

// ✅ Using as const (allowed)
const obj = { x: 1, y: 2 } as const;
const arr = [1, 2, 3] as const;

// ✅ Using as with non-literals (allowed)
const value = getValue() as number;
const result = someVariable as SomeType;

2. literal-type-mismatch: Incompatible type assertions

When you try to assert a literal value to an incompatible type, this rule reports an error without providing a fix (because the code is likely incorrect and needs manual review).

Examples of incorrect code:

// ❌ Type mismatch
const num = "hello" as number;  // Error: Type 'string' is not assignable to type 'number'

// ❌ Wrong union member
type Status = "active" | "inactive";
const status = "pending" as Status;  // Error: Type '"pending"' is not assignable to type 'Status'

// ❌ Missing required properties
interface User { name: string; age: number; }
const user = { name: "John" } as User;  // Error: Property 'age' is missing

🔧 Options

These rules currently have no configuration options.

🤝 When NOT to use these rules

You might want to disable these rules if:

  • You're working with legacy TypeScript code (< 4.9) that doesn't support satisfies
  • You're intentionally using as for type assertions on literals (though we'd recommend reconsidering this)
  • You're using as const exclusively (which is allowed by these rules)

🐛 Compatibility

  • TypeScript: >= 5.0.0 (uses satisfies operator and advanced type checking features)
  • ESLint: >= 8.0.0
  • Node.js: >= 18.0.0

Note: While the satisfies operator was introduced in TypeScript 4.9, this plugin requires TypeScript 5.0+ for full compatibility with its type checking features.

💡 Examples

Before (using as):

interface Config {
  theme: "light" | "dark";
  fontSize: number;
}

const config = {
  theme: "light",
  fontSize: 14
} as Config;

// Type of config.theme is "light" | "dark" (widened)
// Can't access the specific literal type

After (using satisfies):

interface Config {
  theme: "light" | "dark";
  fontSize: number;
}

const config = {
  theme: "light",
  fontSize: 14
} satisfies Config;

// Type of config.theme is "light" (preserved!)
// Can use this specific type in conditional logic

📝 License

ISC © Johannes Vollmer

🙏 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

💖 Support

If you find this plugin helpful, please consider:

🔗 Links