prefer-type-fest-simplify
Require TypeFest Simplify<T> over imported Prettify<T> / Expand<T> aliases.
Targeted pattern scopeโ
This rule only matches type references that resolve to imported Prettify or Expand aliases and can be rewritten as Simplify<T>.
- Type references that resolve to imported
Prettifyaliases. - Type references that resolve to imported
Expandaliases.
Syntactically similar alternatives are intentionally out of scope unless they preserve the same AST shape.
What this rule reportsโ
This rule reports imported Prettify / Expand alias usages that should be replaced with Simplify<T>.
- Type references that resolve to imported
Prettifyaliases. - Type references that resolve to imported
Expandaliases.
Why this rule existsโ
Simplify is the canonical flattening utility provided by type-fest. Standardizing on it reduces utility-name churn across codebases and keeps helper usage consistent with TypeFest defaults.
โ Incorrectโ
import type { Prettify } from "type-aliases";
type ViewModel = Prettify<Base & Extra>;
โ Correctโ
import type { Simplify } from "type-fest";
type ViewModel = Simplify<Base & Extra>;
Behavior and migration notesโ
Simplify<T>normalizes intersections and mapped-type output into a flattened object shape for editor display and assignability workflows.- This rule targets imported alias names with overlapping semantics (
Prettify,Expand). - Keep aliases only when they intentionally add semantics beyond plain type flattening.
Additional examplesโ
โ Incorrect โ Additional exampleโ
import type { Expand } from "type-aliases";
type UIModel = Expand<Base & Extra>;
โ Correct โ Additional exampleโ
import type { Simplify } from "type-fest";
type UIModel = Simplify<Base & Extra>;
โ Correct โ Repository-wide usageโ
type ApiModel = Simplify<ResponseBase & ResponseExtra>;
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-type-fest-simplify": "error",
},
},
];
When not to use itโ
Disable this rule if internal tooling depends on existing alias names.
Package documentationโ
TypeFest package documentation:
Source file: source/simplify.d.ts
/**
Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
@example
```
import type {Simplify} from 'type-fest';
type PositionProps = {
top: number;
left: number;
};
type SizeProps = {
width: number;
height: number;
};
// In your editor, hovering over `Props` will show a flattened object with all the properties.
type Props = Simplify<PositionProps & SizeProps>;
```
Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface.
If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`.
@example
```
import type {Simplify} from 'type-fest';
interface SomeInterface {
foo: number;
bar?: string;
baz: number | undefined;
}
type SomeType = {
foo: number;
bar?: string;
baz: number | undefined;
};
const literal = {foo: 123, bar: 'hello', baz: 456};
const someType: SomeType = literal;
const someInterface: SomeInterface = literal;
declare function fn(object: Record<string, unknown>): void;
fn(literal); // Good: literal object type is sealed
fn(someType); // Good: type is sealed
// @ts-expect-error
fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
```
@link https://github.com/microsoft/TypeScript/issues/15300
@see {@link SimplifyDeep}
@category Object
*/
Rule catalog ID: R066