@@ -125,6 +125,14 @@ pub struct CheckResult {
125125pub static TYPE_CHECK_SNAPSHOT : & [ u8 ] =
126126 include_bytes ! ( concat!( env!( "OUT_DIR" ) , "/PCTX_TYPE_CHECK_SNAPSHOT.bin" ) ) ;
127127
128+ /// TypeScript lib.d.ts files for ES2020 support
129+ ///
130+ /// This JSON contains all TypeScript standard library definition files,
131+ /// providing type definitions for built-in JavaScript types (Array, Promise,
132+ /// Map, console, etc.). These are injected into the type checker runtime
133+ /// to enable full ES2020 type checking.
134+ static TS_LIBS_JSON : & str = include_str ! ( "../ts-libs.json" ) ;
135+
128136// Define the type check extension
129137deno_core:: extension!(
130138 pctx_type_check_snapshot,
@@ -213,6 +221,15 @@ pub async fn type_check(code: &str) -> Result<CheckResult> {
213221 ..Default :: default ( )
214222 } ) ;
215223
224+ // Inject TypeScript lib files as a global variable
225+ let inject_libs_script = format ! (
226+ "globalThis.TS_LIBS = {};" ,
227+ TS_LIBS_JSON
228+ ) ;
229+ js_runtime
230+ . execute_script ( "<inject_ts_libs>" , inject_libs_script)
231+ . map_err ( |e| TypeCheckError :: InternalError ( format ! ( "Failed to inject TS_LIBS: {}" , e) ) ) ?;
232+
216233 // Call the type checking function from the runtime
217234 let code_json =
218235 serde_json:: to_string ( code) . map_err ( |e| TypeCheckError :: InternalError ( e. to_string ( ) ) ) ?;
@@ -248,15 +265,12 @@ pub async fn type_check(code: &str) -> Result<CheckResult> {
248265///
249266/// # Filtered Error Codes
250267///
251- /// The following TypeScript error codes are considered irrelevant and will return `false`:
252- /// - `2307`: Cannot find module (module resolution)
253- /// - `2304`: Cannot find name 'require'
254- /// - `7016`: Could not find declaration file
255- /// - `2580`, `2585`, `2591`: Promise/console not found (runtime provides these)
256- /// - `2693`: Type-only imports (Array, etc.) used as values
268+ /// With ES2020 lib files, the following TypeScript error codes are considered irrelevant:
269+ /// - `2307`: Cannot find module (module resolution handled by runtime)
270+ /// - `2304`: Cannot find name 'require' (not used in ESM)
271+ /// - `7016`: Could not find declaration file (not needed for runtime)
257272/// - `7006`, `7053`, `7005`, `7034`: Implicit any types (JavaScript compatibility)
258- /// - `18046`: Variable of type 'unknown' (reduce operations)
259- /// - `2362`, `2363`: Arithmetic operation strictness
273+ /// - `2362`, `2363`: Arithmetic operation strictness (runtime handles coercion)
260274///
261275/// # Arguments
262276///
@@ -281,15 +295,15 @@ pub async fn type_check(code: &str) -> Result<CheckResult> {
281295/// };
282296/// assert!(is_relevant_error(&type_error));
283297///
284- /// // Console not found - irrelevant (runtime provides it )
285- /// let console_error = Diagnostic {
286- /// message: "Cannot find name 'console '.".to_string(),
298+ /// // Module not found - irrelevant (module resolution handled by runtime )
299+ /// let module_error = Diagnostic {
300+ /// message: "Cannot find module './foo '.".to_string(),
287301/// line: Some(1),
288302/// column: Some(1),
289303/// severity: "error".to_string(),
290- /// code: Some(2580 ),
304+ /// code: Some(2307 ),
291305/// };
292- /// assert!(!is_relevant_error(&console_error ));
306+ /// assert!(!is_relevant_error(&module_error ));
293307/// ```
294308pub fn is_relevant_error ( diagnostic : & Diagnostic ) -> bool {
295309 // Use the shared ignored codes list from ignored_codes module
@@ -312,89 +326,3 @@ pub fn is_relevant_error(diagnostic: &Diagnostic) -> bool {
312326pub fn version ( ) -> & ' static str {
313327 env ! ( "CARGO_PKG_VERSION" )
314328}
315-
316- #[ cfg( test) ]
317- mod tests {
318- use super :: * ;
319-
320- #[ tokio:: test]
321- async fn test_type_check_valid_code ( ) {
322- let code = r"const x: number = 42;" ;
323- let result = type_check ( code) . await . expect ( "type check should not fail" ) ;
324- assert ! ( result. success) ;
325- assert ! ( result. diagnostics. is_empty( ) ) ;
326- }
327-
328- #[ tokio:: test]
329- async fn test_type_check_syntax_error ( ) {
330- let code = r"const x: number = ;" ;
331- let result = type_check ( code) . await . expect ( "type check should not fail" ) ;
332- assert ! ( !result. success) ;
333- assert ! ( !result. diagnostics. is_empty( ) ) ;
334- }
335-
336- #[ test]
337- fn test_is_relevant_error_function ( ) {
338- // Relevant error (type mismatch TS2322)
339- let relevant = Diagnostic {
340- message : "Type 'string' is not assignable to type 'number'." . to_string ( ) ,
341- line : Some ( 1 ) ,
342- column : Some ( 1 ) ,
343- severity : "error" . to_string ( ) ,
344- code : Some ( 2322 ) ,
345- } ;
346- assert ! ( is_relevant_error( & relevant) , "TS2322 should be relevant" ) ;
347-
348- // Irrelevant error (console TS2580)
349- let irrelevant_console = Diagnostic {
350- message : "Cannot find name 'console'." . to_string ( ) ,
351- line : Some ( 1 ) ,
352- column : Some ( 1 ) ,
353- severity : "error" . to_string ( ) ,
354- code : Some ( 2580 ) ,
355- } ;
356- assert ! (
357- !is_relevant_error( & irrelevant_console) ,
358- "TS2580 should be irrelevant"
359- ) ;
360-
361- // Irrelevant error (Promise TS2591)
362- let irrelevant_promise = Diagnostic {
363- message : "Cannot find name 'Promise'." . to_string ( ) ,
364- line : Some ( 1 ) ,
365- column : Some ( 1 ) ,
366- severity : "error" . to_string ( ) ,
367- code : Some ( 2591 ) ,
368- } ;
369- assert ! (
370- !is_relevant_error( & irrelevant_promise) ,
371- "TS2591 should be irrelevant"
372- ) ;
373-
374- // Irrelevant error (implicit any TS7006)
375- let irrelevant_implicit_any = Diagnostic {
376- message : "Parameter implicitly has an 'any' type." . to_string ( ) ,
377- line : Some ( 1 ) ,
378- column : Some ( 1 ) ,
379- severity : "error" . to_string ( ) ,
380- code : Some ( 7006 ) ,
381- } ;
382- assert ! (
383- !is_relevant_error( & irrelevant_implicit_any) ,
384- "TS7006 should be irrelevant"
385- ) ;
386-
387- // Error without code should be relevant
388- let no_code = Diagnostic {
389- message : "Some error" . to_string ( ) ,
390- line : Some ( 1 ) ,
391- column : Some ( 1 ) ,
392- severity : "error" . to_string ( ) ,
393- code : None ,
394- } ;
395- assert ! (
396- is_relevant_error( & no_code) ,
397- "Errors without code should be relevant"
398- ) ;
399- }
400- }
0 commit comments