Loading...
Loading...
Ban `as` type assertions in a package via the `@typescript-eslint/consistent-type-assertions` lint rule, replacing them with compiler-verified type-safe alternatives. Use when enabling the assertion ban in a new package or fixing violations in an existing one.
npx skill4agent add factory-ai/factory-plugins ban-type-assertions@typescript-eslint/consistent-type-assertionsassertionStyle: 'never'as XPick the strictly correct path, not the simpler one.
asas Foo@typescript-eslint/consistent-type-assertions{ assertionStyle: 'never' }packages/<name>/.eslintrc.js.eslintrc.jsrules: {
'@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'never' }],
}cd packages/<name> && npm run lint 2>&1 | grep "consistent-type-assertions"Schema@factory/common@factory/common// BAD
const data = JSON.parse(raw) as MyType;
// GOOD
const data = MySchema.parse(JSON.parse(raw));safeParse// BAD: throws before you can extract the request id
const request = RequestSchema.parse(JSON.parse(raw));
// GOOD: safeParse lets you return a proper error
const parsed = RequestSchema.safeParse(JSON.parse(raw));
if (!parsed.success) {
return errorResponse(rawObj?.id ?? null, INVALID_PARAMS, parsed.error.message);
}
const request = parsed.data;switchininstanceof// BAD
(error as NodeJS.ErrnoException).code
// GOOD
if (error instanceof Error && 'code' in error) {
const code = error.code;
}// BAD
if (METHODS.has(method as Method)) { ... }
// GOOD: switch narrows exhaustively
switch (method) {
case 'foo':
case 'bar':
return handle(method); // narrowed
}// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- ws library types require generic parameter
ws.on('message', handler);// NOT an improvement -- checks shape but not content
function isDaemonRequest(x: unknown): x is DaemonRequest {
return typeof x === 'object' && x !== null && 'method' in x;
}SessionSettingsSchemaz.record(z.unknown())// BAD: accepts anything
const settings = z.record(z.unknown()).parse(raw);
// GOOD: validates against the real shape
const settings = SessionSettingsSchema.parse(raw);@factory/common@factory/common/<domain>/<subdomain>/schema.tsenums.tsfactory/enum-file-organization@factory/common/session/summaryindex.tsnpm run knipas X.parse()function mockSessionSummary(
overrides?: Partial<SessionSummaryEvent>,
): SessionSummaryEvent {
return {
type: 'session_start',
id: 'test-id',
title: 'Test Session',
owner: 'test-owner',
...overrides,
};
}// BAD: parse outside try/catch -- if it throws, you lose context
const request = RequestSchema.parse(data);
try { handle(request); } catch { ... }
// GOOD: safeParse before try, handle error with context
const parsed = RequestSchema.safeParse(data);
if (!parsed.success) {
return errorResponse(rawData?.id ?? null, INVALID_PARAMS, parsed.error.message);
}
try { handle(parsed.data); } catch { ... }@factory/common# Lint (all affected packages)
cd packages/<name> && npm run lint
# Typecheck
npm run typecheck
# Tests
npm run test
# Unused exports (repo root)
npm run knipfactory/enum-file-organizationenums.tsno-barrel-filespackage.json.eslintrc.js