Skip to content

Commit

Permalink
fix(check): better handling of TypeScript in npm packages for type ch…
Browse files Browse the repository at this point in the history
…ecking (#27853)

1. Allows resolving to `.ts` files for type checking.
2. Probes for `.ts` files to use for type checking.

To emphasize, this is only for type checking.
  • Loading branch information
dsherret authored Jan 28, 2025
1 parent a5a1cce commit 7528c79
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 12 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions resolvers/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async-trait.workspace = true
boxed_error.workspace = true
dashmap.workspace = true
deno_error.workspace = true
deno_media_type.workspace = true
deno_package_json.workspace = true
deno_path_util.workspace = true
futures.workspace = true
Expand Down
26 changes: 14 additions & 12 deletions resolvers/node/resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::path::PathBuf;

use anyhow::bail;
use anyhow::Error as AnyError;
use deno_media_type::MediaType;
use deno_package_json::PackageJson;
use serde_json::Map;
use serde_json::Value;
Expand Down Expand Up @@ -496,18 +497,18 @@ impl<
fn probe_extensions<TSys: FsMetadata>(
sys: &TSys,
path: &Path,
lowercase_path: &str,
media_type: MediaType,
resolution_mode: ResolutionMode,
) -> Option<PathBuf> {
let mut searched_for_d_mts = false;
let mut searched_for_d_cts = false;
if lowercase_path.ends_with(".mjs") {
if media_type == MediaType::Mjs {
let d_mts_path = with_known_extension(path, "d.mts");
if sys.fs_is_file_no_err(&d_mts_path) {
return Some(d_mts_path);
}
searched_for_d_mts = true;
} else if lowercase_path.ends_with(".cjs") {
} else if media_type == MediaType::Cjs {
let d_cts_path = with_known_extension(path, "d.cts");
if sys.fs_is_file_no_err(&d_cts_path) {
return Some(d_cts_path);
Expand All @@ -534,18 +535,19 @@ impl<
return Some(specific_dts_path);
}
}
let ts_path = with_known_extension(path, "ts");
if sys.fs_is_file_no_err(&ts_path) {
return Some(ts_path);
}
None
}

let lowercase_path = path.to_string_lossy().to_lowercase();
if lowercase_path.ends_with(".d.ts")
|| lowercase_path.ends_with(".d.cts")
|| lowercase_path.ends_with(".d.mts")
{
let media_type = MediaType::from_path(&path);
if media_type.is_declaration() {
return Ok(UrlOrPath::Path(path));
}
if let Some(path) =
probe_extensions(&self.sys, &path, &lowercase_path, resolution_mode)
probe_extensions(&self.sys, &path, media_type, resolution_mode)
{
return Ok(UrlOrPath::Path(path));
}
Expand All @@ -565,14 +567,14 @@ impl<
if let Some(path) = probe_extensions(
&self.sys,
&index_path,
&index_path.to_string_lossy().to_lowercase(),
MediaType::from_path(&index_path),
resolution_mode,
) {
return Ok(UrlOrPath::Path(path));
}
}
// allow resolving .css files for types resolution
if lowercase_path.ends_with(".css") {
// allow resolving .ts-like or .css files for types resolution
if media_type.is_typed() || media_type == MediaType::Css {
return Ok(UrlOrPath::Path(path));
}
Err(TypesNotFoundError(Box::new(TypesNotFoundErrorData {
Expand Down
5 changes: 5 additions & 0 deletions tests/specs/check/ts_in_npm_pkg/__test__.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"args": "check --all main.ts",
"output": "check.out",
"exitCode": 1
}
7 changes: 7 additions & 0 deletions tests/specs/check/ts_in_npm_pkg/check.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Check file:///[WILDLINE]/main.ts
TS2322 [ERROR]: Type 'string' is not assignable to type 'Test'.
const test: Test = "";
~~~~
at file:///[WILDLINE]/main.ts:3:7

error: Type checking failed.
3 changes: 3 additions & 0 deletions tests/specs/check/ts_in_npm_pkg/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { Test } from "package";

const test: Test = "";

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tests/specs/check/ts_in_npm_pkg/node_modules/package/other.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions tests/specs/check/ts_in_npm_pkg/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}

0 comments on commit 7528c79

Please sign in to comment.