prefer-ts-extras-as-writable
Prefer asWritable from ts-extras over Writable<...> type assertions.
Targeted pattern scopeโ
This rule focuses on mutation-intent type assertions that map directly to asWritable(value).
Matched patternsโ
asassertions where the asserted type isWritable<...>imported fromtype-fest.- Namespace-qualified assertions such as
TypeFest.Writable<...>whenTypeFestcomes fromtype-fest.
Detection boundariesโ
- โ
Reports
Writable-based type assertions that are direct helper replacements. - โ Does not report unrelated
asassertions with non-Writabletarget types.
These boundaries keep matching deterministic and avoid broad semantic overreach during migration.
What this rule reportsโ
Writable<...>-based type assertions that can be replaced with asWritable(value).
Why this rule existsโ
asWritable(value) communicates intent directly and keeps mutation-intent casts aligned with the ts-extras helper API.
โ Incorrectโ
import type { Writable } from "type-fest";
const writableUser = readonlyUser as Writable<User>;
โ Correctโ
import { asWritable } from "ts-extras";
const writableUser = asWritable(readonlyUser);
Behavior and migration notesโ
asWritable(value)preserves runtime behavior while expressing mutability intent through one helper.- Direct
as Writable<T>/as TypeFest.Writable<T>assertions are reported. - This rule does not rewrite unrelated type assertions.
Additional examplesโ
โ Incorrect โ Additional exampleโ
const mutable = config as Writable<typeof config>;
โ Correct โ Additional exampleโ
const mutable = asWritable(config);
โ Correct โ Repository-wide usageโ
const draft = asWritable(readonlyDraft);
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-ts-extras-as-writable": "error",
},
},
];
When not to use itโ
Disable this rule if mutation boundaries are enforced through explicit type assertions by policy.
Package documentationโ
ts-extras package documentation:
Source file: source/as-writable.ts
/**
Cast the given value to be [`Writable`](https://github.com/sindresorhus/type-fest/blob/main/source/writable.d.ts).
This is useful because of a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/45618#issuecomment-908072756).
@example
```
import {asWritable} from 'ts-extras';
const writableContext = asWritable((await import('x')).context);
```
@category General
*/
Rule catalog ID: R010