Skip to content

Prevent getTypeAtLocation crash on type-only import clause - #64468

Open
lsh4711 wants to merge 1 commit into
microsoft:mainfrom
lsh4711:fix-type-only-import-clause-crash
Open

lsh4711 wants to merge 1 commit into
microsoft:mainfrom
lsh4711:fix-type-only-import-clause-crash

Conversation

@lsh4711

@lsh4711 lsh4711 commented Sep 26, 2026

Copy link
Copy Markdown

Fixes #64467

Context

I'm building syscript, a compiler that compiles TypeScript syntax to C for systems
programming. It uses the TypeScript 7 API to type-check the program and then walks
every node, requesting its type in a batch with getTypeAtLocation. That walk crashed
the API server on the first file that used import type.

Problem

checker.GetTypeAtLocation panics with a nil pointer dereference when called on the
ImportClause of a type-only import without a default binding:

// types.ts
export type U = number;
// main.ts
import type { U } from "./types";
import type * as types from "./types";
panic: runtime error: invalid memory address or nil pointer dereference
checker.(*Checker).tryGetDeclaredTypeOfSymbol
checker.(*Checker).getDeclaredTypeOfSymbol
checker.(*Checker).getTypeOfNode
checker.(*Checker).GetTypeAtLocation

It reproduces with the latest nightly (typescript@7.1.0-dev.20260926.1).

Cause

ast.IsTypeDeclaration returns true for a type-only ImportClause, so getTypeOfNode
takes the type-declaration branch and passes the result of getSymbolOfDeclaration
straight to getDeclaredTypeOfSymbol. An import clause only has a symbol when it has
a default binding (import type X from "..."), so for import type { U } and
import type * as ns the symbol is nil.

The missing check looks historical rather than intentional. When this branch was
written, isTypeDeclaration only covered type parameters, classes, interfaces, type
aliases and enums, which always have a symbol. #35200 (type-only imports and exports)
added ImportClause, ImportSpecifier and ExportSpecifier; the specifiers always
have a symbol, but a clause without a default binding does not. The same unguarded
branch is still in Strada's getTypeOfNode, and this code was ported from it.

Fix

Return errorType when the declaration has no symbol, matching the neighboring
IsTypeDeclarationName and IsDeclaration branches, which already guard against a nil
symbol.

This also makes type-only clauses consistent with regular ones: a regular
import { U } from "./types" clause is not a type declaration, so it already reaches
the IsDeclaration branch and gets errorType there.

Tests

Added TestGetTypeAtLocationOfTypeOnlyImportClause in internal/checker. It requests
the type of a named and a namespace type-only import clause and checks that both match
the type of an equivalent regular import clause. It panics without the fix and passes
with it.

Ran the pre-submission checklist from CONTRIBUTING.md. Everything passes except
internal/vfs/osvfs TestOS/Realpath, which also fails on main in my environment
because my home directory is a symlink (/home → /var/home, Fedora Atomic).


I used Claude Code for this change; I've reviewed it and will handle the review.

Copilot AI balanced review requested due to automatic review settings September 26, 2026 14:04
@typescript-automation typescript-automation Bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Sep 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@lsh4711

lsh4711 commented Sep 26, 2026

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@lsh4711
lsh4711 requested a balanced review from Copilot September 26, 2026 19:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

getTypeAtLocation crashes on the ImportClause of a type-only import

2 participants