prefer-type-fest-partial-deep
Require TypeFest PartialDeep over DeepPartial aliases.
Targeted pattern scopeโ
This rule reports DeepPartial<T> aliases and prefers PartialDeep<T> for recursive optional patch types.
What this rule reportsโ
- Type references named
DeepPartial.
Detection boundariesโ
- โ
Reports direct
DeepPartial<T>type references. - โ Does not auto-fix where project-local aliases have non-TypeFest semantics.
Why this rule existsโ
PartialDeep<T> is the canonical TypeFest utility for recursive optionality.
Using a single name for deep patch semantics makes update/persistence DTOs easier to audit.
โ Incorrectโ
type Patch = DeepPartial<AppConfig>;
โ Correctโ
import type { PartialDeep } from "type-fest";
type Patch = PartialDeep<AppConfig>;
Behavior and migration notesโ
PartialDeep<T>recursively marks nested properties optional.- Validate parity if your legacy alias excluded arrays, maps, or sets.
- Prefer narrowing the patch surface with
Pick/Exceptbefore applying deep optionality.
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-type-fest-partial-deep": "error",
},
},
];
When not to use itโ
Disable this rule if your codebase intentionally standardizes DeepPartial naming instead of TypeFest.
Package documentationโ
TypeFest package documentation:
Source file: source/partial-deep.d.ts
/**
* Create a type from another type with all keys and nested keys set to
* optional.
*
* Use-cases:
*
* - Merging a default settings/config object with another object, the second
* object would be a deep partial of the default object.
* - Mocking and testing complex entities, where populating an entire object with
* its keys would be redundant in terms of the mock or test.
*
* @category Object
* @category Array
* @category Set
* @category Map
*
* @example
* ```
* import type {PartialDeep} from 'type-fest';
*
* let settings = {
* textEditor: {
* fontSize: 14,
* fontColor: '#000000',
* fontWeight: 400,
* },
* autocomplete: false,
* autosave: true,
* };
*
* const applySavedSettings = (savedSettings: PartialDeep<typeof settings>) => (
* {...settings, ...savedSettings, textEditor: {...settings.textEditor, ...savedSettings.textEditor}}
* );
*
* settings = applySavedSettings({textEditor: {fontWeight: 500}});
* ```
*
* By default, this does not affect elements in array and tuple types. You can change this by passing `{recurseIntoArrays: true}` as the second type argument:
*
* ```
* import type {PartialDeep} from 'type-fest';
*
* type Shape = {
* dimensions: [number, number];
* };
*
* const partialShape: PartialDeep<Shape, {recurseIntoArrays: true}> = {
* dimensions: [], // OK
* };
*
* partialShape.dimensions = [15]; // OK
* ```
*
* @see {@link PartialDeepOptions}
*/
Rule catalog ID: R052