Skip to content

volar-service-typescript and volar-service-typescript-twoslash-queries import typescript types without declaring it #125

Description

@zkochan

volar-service-typescript@0.0.71 and volar-service-typescript-twoslash-queries@0.0.71 import typescript from their type declarations, but neither manifest declares typescript in dependencies or peerDependencies.

package .d.ts files importing typescript example
volar-service-typescript 14 index.d.ts:4export declare function create(ts: typeof import('typescript'), …)
volar-service-typescript-twoslash-queries 1 index.d.ts:2export declare function create(ts: typeof import('typescript')): LanguageServicePlugin

Why it matters

With a hoisting installer (npm / Yarn classic) this resolves by accident, because typescript gets flattened into the top-level node_modules. With an isolated layout it only resolves when the package's real path happens to sit under a node_modules that has typescript as an ancestor. Two setups where that ancestor walk fails, both verified:

  • A store outside the project — pnpm's global virtual store, and any comparable content-addressed layout.
  • Hoisting disabled (hoist=false / hoistPattern: []), even with the ordinary project-local store.

In those cases tsc reports Cannot find module 'typescript' or its corresponding type declarations inside the published .d.ts, every ts.* type silently degrades to any, and downstream module augmentation stops applying — so consumers see errors that look unrelated to a missing dependency.

Suggested fix

An optional peer dependency keeps the runtime contract intact — both packages receive the ts instance from their caller and never require('typescript') themselves — while making the types resolvable:

{
  "peerDependencies": {
    "typescript": "*"
  },
  "peerDependenciesMeta": {
    "typescript": {
      "optional": true
    }
  }
}

Optional matters here: a required peer would make installers pull typescript into projects that only consume the runtime.

The same problem affects @volar/typescript, @volar/language-server and @volar/language-service in volarjs/volar.js; it is tracked there as volarjs/volar.js#284.

Happy to send a PR for both packages if that direction looks right to you.


Written by an agent (Claude Code, claude-opus-5), on behalf of the pnpm maintainers — this surfaced while triaging pnpm/pnpm#13331.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions