Skip to content

Commit

Permalink
feat(isolated-declarations): improve the inference template literal (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Dunqing committed Jun 20, 2024
1 parent b0d7355 commit a37138f
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 28 deletions.
7 changes: 6 additions & 1 deletion crates/oxc_isolated_declarations/src/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ impl<'a> IsolatedDeclarations<'a> {
if let Some(init_expr) = &decl.init {
// if kind is const and it doesn't need to infer type from expression
if decl.kind.is_const() && !Self::is_need_to_infer_type_from_expression(init_expr) {
init = Some(self.ast.copy(init_expr));
if let Expression::TemplateLiteral(lit) = init_expr {
init =
self.transform_template_to_string(lit).map(Expression::StringLiteral);
} else {
init = Some(self.ast.copy(init_expr));
}
} else {
// otherwise, we need to infer type from expression
binding_type = self.infer_type_from_expression(init_expr);
Expand Down
21 changes: 13 additions & 8 deletions crates/oxc_isolated_declarations/src/inferrer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ impl<'a> IsolatedDeclarations<'a> {
Expression::NumericLiteral(_) | Expression::BigintLiteral(_) => {
Some(self.ast.ts_number_keyword(SPAN))
}
Expression::StringLiteral(_) | Expression::TemplateLiteral(_) => {
Some(self.ast.ts_string_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::Identifier(ident) => match ident.name.as_str() {
"undefined" => Some(self.ast.ts_undefined_keyword(SPAN)),
Expand Down Expand Up @@ -133,12 +138,12 @@ impl<'a> IsolatedDeclarations<'a> {
}

pub fn is_need_to_infer_type_from_expression(expr: &Expression) -> bool {
!matches!(
expr,
match expr {
Expression::NumericLiteral(_)
| Expression::BigintLiteral(_)
| Expression::StringLiteral(_)
| Expression::TemplateLiteral(_)
)
| Expression::BigintLiteral(_)
| Expression::StringLiteral(_) => false,
Expression::TemplateLiteral(lit) => !lit.expressions.is_empty(),
_ => true,
}
}
}
1 change: 1 addition & 0 deletions crates/oxc_isolated_declarations/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod diagnostics;
mod r#enum;
mod function;
mod inferrer;
mod literal;
mod module;
mod return_type;
mod scope;
Expand Down
22 changes: 22 additions & 0 deletions crates/oxc_isolated_declarations/src/literal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use oxc_allocator::Box;
use oxc_ast::ast::{StringLiteral, TemplateLiteral};

use crate::IsolatedDeclarations;

impl<'a> IsolatedDeclarations<'a> {
pub fn transform_template_to_string(
&self,
lit: &TemplateLiteral<'a>,
) -> Option<Box<'a, StringLiteral<'a>>> {
if lit.expressions.is_empty() {
lit.quasis.first().map(|item| {
self.ast.alloc(self.ast.string_literal(
lit.span,
if let Some(cooked) = &item.value.cooked { cooked } else { &item.value.raw },
))
})
} else {
None
}
}
}
22 changes: 3 additions & 19 deletions crates/oxc_isolated_declarations/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,25 +189,9 @@ impl<'a> IsolatedDeclarations<'a> {
"undefined" => Some(self.ast.ts_undefined_keyword(ident.span)),
_ => None,
},
Expression::TemplateLiteral(lit) => {
if lit.expressions.is_empty() {
lit.quasis.first().map(|item| {
self.ast.ts_literal_type(
SPAN,
TSLiteral::StringLiteral(self.ast.alloc(self.ast.string_literal(
lit.span,
if let Some(cooked) = &item.value.cooked {
cooked
} else {
&item.value.raw
},
))),
)
})
} else {
None
}
}
Expression::TemplateLiteral(lit) => self
.transform_template_to_string(lit)
.map(|string| self.ast.ts_literal_type(lit.span, TSLiteral::StringLiteral(string))),
Expression::UnaryExpression(expr) => Some(
self.ast.ts_literal_type(SPAN, TSLiteral::UnaryExpression(self.ast.copy(expr))),
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const CSS_VARS_HELPER = `useCssVars`

export function g(func = `useCssVar`) : void {}

export const F = {
a: `a`,
b: [`b`]
} as const

export const BAD = `useCssV${v}ars`
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
source: crates/oxc_isolated_declarations/tests/mod.rs
input_file: crates/oxc_isolated_declarations/tests/fixtures/infer-template-literal.ts
---
==================== .D.TS ====================

export declare const CSS_VARS_HELPER = 'useCssVars';
export declare function g(func?: string): void;
export declare const F: {
readonly a: 'a';
readonly b: readonly ['b'];
};
export declare const BAD: unknown;


==================== Errors ====================

x TS9010: Variable must have an explicit type annotation with
| --isolatedDeclarations.
,-[10:14]
9 |
10 | export const BAD = `useCssV${v}ars`
: ^^^
`----

0 comments on commit a37138f

Please sign in to comment.