Conversation
…l's type argument
A type parameter that appears in none of a signature's parameters can only be
inferred from the return position, or else fall back to its default. When such a
call is the operand of a type assertion, the assertion is what the type argument
gets inferred from, so the operand ends up with exactly the asserted type and the
assertion looks like it changes nothing.
It does. Dropping `query('k') as Derived` from
declare function query<T extends Base = Base>(key: string): T;
const v = query('k') as Derived;
falls back to `T = Base`, and the code stops compiling - but the rule reported it
and the autofix removed it.
`getUncastType` already asks for the context-free type to keep that inference out
of the comparison, but the checker caches a call's resolved signature per node,
so once anything has checked the call the context-free type *is* the contextual
one. Reporting TypeScript's type errors alongside lint diagnostics (oxlint's
`--type-check`) checks every file up front and made this reproduce every time;
without it, whether it reproduced depended on what else had already been checked.
Detect the shape instead of relying on checker state: an (optionally awaited)
call, new, or tagged template with no type arguments written, whose resolved
signature declares a type parameter that no parameter mentions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1141.
A type parameter that appears in none of a signature's parameters can only be inferred from the return position, or else fall back to its default. When such a call is the operand of a type assertion, the assertion is what the type argument gets inferred from, so the operand ends up with exactly the asserted type and the assertion looks like it changes nothing. It isn't — removing it drops the type argument back to its default and the code stops compiling, which is what the autofix did.
getUncastTypealready asks for the context-free type to keep that inference out of the comparison (#824), but the checker caches a call's resolved signature per node, so the guard only holds while nothing else has checked the call. Reporting type errors alongside lint diagnostics (ReportSemantic: true, oxlint's--type-check) checks every file first and defeats it every time; without it, whether the rule fired came down to concurrent scheduling.Summary
linter.RunLinterOnProgramwithReportSemantic: true, since the existing rule tester runs with type errors off, where the bug does not reproduceTests
go test ./internal/...cd e2e && pnpm --ignore-workspace run test --runAI disclosure: this change was produced with AI assistance (Claude Code) and reviewed by me.