diff --git a/crates/oxc_isolated_declarations/src/declaration.rs b/crates/oxc_isolated_declarations/src/declaration.rs index 8c0307326914..5df2773bdd61 100644 --- a/crates/oxc_isolated_declarations/src/declaration.rs +++ b/crates/oxc_isolated_declarations/src/declaration.rs @@ -77,7 +77,9 @@ impl<'a> IsolatedDeclarations<'a> { } else { init = Some(self.ast.copy(init_expr)); } - } else { + } else if !decl.kind.is_const() + || !matches!(init_expr, Expression::TemplateLiteral(_)) + { // otherwise, we need to infer type from expression binding_type = self.infer_type_from_expression(init_expr); } diff --git a/crates/oxc_isolated_declarations/src/inferrer.rs b/crates/oxc_isolated_declarations/src/inferrer.rs index ea83c09d9039..153e9153f637 100644 --- a/crates/oxc_isolated_declarations/src/inferrer.rs +++ b/crates/oxc_isolated_declarations/src/inferrer.rs @@ -24,13 +24,8 @@ impl<'a> IsolatedDeclarations<'a> { Expression::NullLiteral(_) => Some(self.ast.ts_null_keyword(SPAN)), Expression::NumericLiteral(_) => Some(self.ast.ts_number_keyword(SPAN)), Expression::BigIntLiteral(_) => Some(self.ast.ts_bigint_keyword(SPAN)), - Expression::StringLiteral(_) => Some(self.ast.ts_string_keyword(SPAN)), - Expression::TemplateLiteral(lit) => { - if lit.expressions.is_empty() { - Some(self.ast.ts_string_keyword(SPAN)) - } else { - None - } + Expression::StringLiteral(_) | Expression::TemplateLiteral(_) => { + Some(self.ast.ts_string_keyword(SPAN)) } Expression::Identifier(ident) => match ident.name.as_str() { "undefined" => Some(self.ast.ts_undefined_keyword(SPAN)), diff --git a/crates/oxc_isolated_declarations/tests/fixtures/arrow-function-return-type.ts b/crates/oxc_isolated_declarations/tests/fixtures/arrow-function-return-type.ts index 34e91d499ce7..a188069a364d 100644 --- a/crates/oxc_isolated_declarations/tests/fixtures/arrow-function-return-type.ts +++ b/crates/oxc_isolated_declarations/tests/fixtures/arrow-function-return-type.ts @@ -6,4 +6,6 @@ function A() { const B = () => { return B }; -const C = function () {} \ No newline at end of file +const C = function () {} + +const D = () => `${''}`; \ No newline at end of file diff --git a/crates/oxc_isolated_declarations/tests/fixtures/infer-return-type.ts b/crates/oxc_isolated_declarations/tests/fixtures/infer-return-type.ts index dde956921836..2a489ed8e1a7 100644 --- a/crates/oxc_isolated_declarations/tests/fixtures/infer-return-type.ts +++ b/crates/oxc_isolated_declarations/tests/fixtures/infer-return-type.ts @@ -23,5 +23,10 @@ function qux() { const a = (() => { return 1; })(); - return `Hello, world!`; -} \ No newline at end of file + return `Hello, world!`; +} + +function quux() { + return `${''}` +} +// Inferred type is string \ No newline at end of file diff --git a/crates/oxc_isolated_declarations/tests/fixtures/infer-template-literal.ts b/crates/oxc_isolated_declarations/tests/fixtures/infer-template-literal.ts index 875168425145..dca3f8568ec6 100644 --- a/crates/oxc_isolated_declarations/tests/fixtures/infer-template-literal.ts +++ b/crates/oxc_isolated_declarations/tests/fixtures/infer-template-literal.ts @@ -7,4 +7,8 @@ export const F = { b: [`b`] } as const -export const BAD = `useCssV${v}ars` \ No newline at end of file +export let GOOD = `useCssV${v}ars` + +export const BAD = `useCssV${v}ars` + +export let BAD2 = `useCssV${v}ars` as const \ No newline at end of file diff --git a/crates/oxc_isolated_declarations/tests/snapshots/arrow-function-return-type.snap b/crates/oxc_isolated_declarations/tests/snapshots/arrow-function-return-type.snap index 1949cf59f2a5..cae808cef8ba 100644 --- a/crates/oxc_isolated_declarations/tests/snapshots/arrow-function-return-type.snap +++ b/crates/oxc_isolated_declarations/tests/snapshots/arrow-function-return-type.snap @@ -7,6 +7,7 @@ input_file: crates/oxc_isolated_declarations/tests/fixtures/arrow-function-retur declare function A(): unknown; declare const B: unknown; declare const C: unknown; +declare const D: () => string; ==================== Errors ==================== @@ -31,8 +32,9 @@ declare const C: unknown; x TS9007: Function must have an explicit return type annotation with | --isolatedDeclarations. - ,-[9:20] - 8 | - 9 | const C = function () {} - : ^ - `---- + ,-[9:20] + 8 | + 9 | const C = function () {} + : ^ + 10 | + `---- diff --git a/crates/oxc_isolated_declarations/tests/snapshots/infer-return-type.snap b/crates/oxc_isolated_declarations/tests/snapshots/infer-return-type.snap index 10baf48c509a..a7cd26e84a9f 100644 --- a/crates/oxc_isolated_declarations/tests/snapshots/infer-return-type.snap +++ b/crates/oxc_isolated_declarations/tests/snapshots/infer-return-type.snap @@ -8,6 +8,7 @@ declare function foo(): number; declare function bar(): number | undefined; declare function baz(); declare function qux(): string; +declare function quux(): string; ==================== Errors ==================== diff --git a/crates/oxc_isolated_declarations/tests/snapshots/infer-template-literal.snap b/crates/oxc_isolated_declarations/tests/snapshots/infer-template-literal.snap index b869fbd280c0..fcef01f361c4 100644 --- a/crates/oxc_isolated_declarations/tests/snapshots/infer-template-literal.snap +++ b/crates/oxc_isolated_declarations/tests/snapshots/infer-template-literal.snap @@ -10,15 +10,26 @@ export declare const F: { readonly a: 'a'; readonly b: readonly ['b']; }; +export declare let GOOD: string; export declare const BAD: unknown; +export declare let BAD2: unknown; ==================== Errors ==================== x TS9010: Variable must have an explicit type annotation with | --isolatedDeclarations. - ,-[10:14] - 9 | - 10 | export const BAD = `useCssV${v}ars` + ,-[12:14] + 11 | + 12 | export const BAD = `useCssV${v}ars` : ^^^ + 13 | + `---- + + x TS9010: Variable must have an explicit type annotation with + | --isolatedDeclarations. + ,-[14:12] + 13 | + 14 | export let BAD2 = `useCssV${v}ars` as const + : ^^^^ `----